Does anyone here have a good understanding of the relative merits of Zig, Crystal, and Nim? Especially compared to higher profile languages like Rust and Go?
All of these languages seem to be statically compiled, and they all seem to promise both performance and safety. Rust and Go are discussed all the time on HN, so I expect most of us here have a reasonable notion of their relative benefits, for example, performance compared to ease of learning.
What about these lesser discussed languages Zig, Nim, and Crystal? Are their runtime performances comparable to one another? Are they equally safe to program in? What are their relative strengths? Or does it just come down to syntax preference?
I think there's value in having a lot of choices to program in, so I'm not asking which language is "best" any absolute sense. We're better off for having all of these languages coexisting. I'm just asking if anyone with experience in the three of them has any insight or impressions of their relative merits.
Zig and Rust both don't have a runtime/GC, they should be on par with performance in C, meaning they are slightly faster than the others (of course this all depends). Go is the only one you listed that doesn't have some kind of parametric polymorphism support (generics). Rust is the only one that will validate your program is memory safe at compile time, they call this 'data race freedom'.
I think in the end it's really up to your tastes which you prefer. Have a look at the tenets of each of the languages and see which resonates with you.
Maybe, but libraries that you use in Nim will probably use the GC, so will many functions in the std library (I imagine). Additionally, the binary you ship will still probably include the runtime & GC. So it's not really fair to say it's on par with C/Rust, there's reasons to avoid GC besides just performance. Say you are writing an embedded application for example. I don't know any Nim, so correct me if I'm wrong.
Having looked at all three, I've so far settled on Zig for a couple reasons:
- Cross-compilation is trivial (I haven't dug too deeply into the cross-compilation story on Nim and Crystal, but Zig's is front-and-center)
- Allocations are explicit (functions that require allocating memory do so by accepting an allocator as an argument)
- Windows support seems to be better than with Crystal (which means I can use Zig for desktop programming for my dayjob, since at work most of the PCs here run Windows 10; not that I would at the moment, given that it's very much not production ready yet, but still)
- I strongly dislike Python's syntax, and therefore strongly dislike Nim's syntax (I also somewhat dislike C's syntax - and therefore Zig's - but not nearly as strongly)
- Zig's build system is pretty great (albeit not exactly intelligent when it comes to finding system header and library paths, I've noticed)
That said, there are some downsides to Zig that I'm hoping can be resolved (whether by someone else or - if I get comfortable enough with it - myself):
- Profound lack of standard library documentation
- I like Crystal's syntax better
- C++ interoperability is practically nonexistent (though it might be possible to write small C++ shims that link against Zig-outputted headers; not sure if Zig's included C compiler can compile those, but if it can, then this would be easy to integrate into the build process)
That is true. I only brought it up as a comparison with e.g. Nim, which does (claim to) have the ability to interoperate with C++ directly without C-ABI shims. D supposedly has similar capabilities, as does Chicken Scheme.
But yeah, the use case ain't to work with C++ code I've written (if I'm writing it, then my goal is to write as close to zero lines of C++ as possible ;) ), but rather to work with third-party C++ codebases that do not expose a C-compatible API (or do so poorly).
I don't know about Crystal but Nim GC is optional and even on a per-type basis:
Use plain object and you are on the stack
Use ptr object and you can use any allocator you want (Nim's default, malloc/free or jemalloc, mimalloc, ...)
Use ref object and your reference will be managed by the GC.
In terms of GC, you the default is deferred reference counting (no ref counting if object is created and destroyed at the end of the scope).
It accepts real-time and max-pause tunings parameters, to allow it to stay beyond those 60FPS / 144 FPS requirements
You can also choose java-like mark-and-sweep, the Boehm GC, the go GC, or no GC and get a warning everytime you try to use a type that uses the GC.
All of these languages seem to be statically compiled, and they all seem to promise both performance and safety. Rust and Go are discussed all the time on HN, so I expect most of us here have a reasonable notion of their relative benefits, for example, performance compared to ease of learning.
What about these lesser discussed languages Zig, Nim, and Crystal? Are their runtime performances comparable to one another? Are they equally safe to program in? What are their relative strengths? Or does it just come down to syntax preference?
I think there's value in having a lot of choices to program in, so I'm not asking which language is "best" any absolute sense. We're better off for having all of these languages coexisting. I'm just asking if anyone with experience in the three of them has any insight or impressions of their relative merits.