The more I use Rust the more I am convinced I can write high level performant code. I mean it's ridiculous that sometimes I forget I am writing Rust and not Scala!!
As someone who does a lot of low-level development, before Zig I didn't think any approach other than that of C or that of C++ was even possible. I don't know if Zig will fulfil its promise, but its radical design, that's unlike anything we've ever seen, sure offers a fresh perspective on things.
As to static guarantees -- they are never the point; they are a means to an end: writing more correct programs. That goal is just as valued by Zig as it is by Rust, Zig just tries to achieve it differently. Which achieves it better? It's hard to know right now. I have little doubt that Rust could make things that are today written in C++ safer, but I have serious doubts whether it would be adopted in truly safety-critical domains, where C is king. I think Zig could be.
I didn't know Zig can provide memory safety using it's features. If that's the case it's great, I need to try it out! Although I am sceptical about the claim that in truly safety-critical domains Rust would not be adopted where Zig would, but I am again out of my depth here, so :)
Yes, although this is done through runtime checks (that can be optionally disabled) rather than through static sound guarantees (Rust uses runtime checks in some cases, too). The language's simplicity and fast compilation helps with other types of correctness, too (i.e. beyond memory safety).
> Although I am sceptical about the claim that in truly safety-critical domains Rust would not be adopted where Zig would
I don't know if Zig would, but Rust has several problems for such domains that C and Zig don't: porting it is a challenge (both Rust itself and LLVM are very complex), understanding what a program does is a challenge (a lot of implicit behaviour), and handling allocation failures is a challenge.
Zig also has the same issue with LLVM until the language is fully bootstraped and the original LLVM based compiler no longer part of the build process.
However, packaging a C and C++ compiler alongside for the ride doesn't make it that much simpler.
That might not matter. Porting Rust might not be a simple undertaking, either.
> Zig also has the same issue with LLVM until the language is fully bootstraped and the original LLVM based compiler no longer part of the build process.
Yes, but that's expected to happen before 1.0.
> However, packaging a C and C++ compiler alongside for the ride doesn't make it that much simpler.
C isn't an issue at all; C++ is. I'm pretty sure it could be made optional.
Procedural macros are also somewhat insane in many ways.
It seeks too, but fails. Comparing to really-simple C, it's full of arcane stuff.
> Zig rejects any kind of implicitness; all calls must appear as calls.
We already have that in C.
> Of course, that illusion breaks as soon as you try to change code
That's one of the traits of Zig too it seems. My favorite example of Zig's poor design is following case:
Suppose you have a function call:
collectNoInline(gc);
And you want to annotate it for being never-inlined (call-site level annotation for "always inline" and "never inline" is a customary enough task in low-level programming). So, in Zig, annotated call transforms too: @call(.{ .modifier = .never_inline }, collectNoInline, .{gc});
Ref: https://ziglang.org/documentation/master/#callI'm sorry, but that's total nonsense. Shows that not enough good faith went into Zig design. Even in C, that could be syntactically annotated as:
/*pragma:noinline*/
collectNoInline(gc);I think it's quite the opposite. Don't forget that C also has macros and a lot of arcane undefined behaviour. I don't know if Zig is as simple as C -- it doesn't have macros but does have, say, slices and comptime -- but it's also much safer and much more expressive. Overall, it's a very simple language, that's very expressive and also quite safe.
> That's one of the traits of Zig too it seems.
Absolutely! It's a feature of all low-level languages. Zig, however, unlike C++ and Rust, doesn't try to waste its complexity budget on making it seem like a high-level language when you just look at the code on the page (and it has other downsides, too, besides language complexity).
> I'm sorry, but that's total nonsense. Shows that not enough good faith went into Zig design. Even in C, that could be syntactically annotated as:
And I'm sorry, too, but I would say it's an example of Zig's exceptionally great design at this stage. If at some point it turns out that adding a new kind of syntax element here is worthwhile, it can always be added later. When in doubt -- leave it out. You never know when your complexity budget is best spent, and if you already have a general means of doing something without a new syntactic category, it's best to wait and see.
C lexic-based "macros" are implemented by a separate component, "C preprocessor". C clearly needs a AST-based macros, not a whole new language to replace it. Undefined behavior comes from the fact that C is machine-independent assembler (with structured syntax), so to be exactly that ("machine-independent" and "assembler"), it has to underspecify machine-specific matters, like what happens if you shift 32-bit number by 33 bits.
> I don't know if Zig is as simple as C -- it doesn't have macros but does have, say, slices and comptime -- but it's also much safer and much more expressive. Overall, it's a very simple language, that's very expressive and also quite safe.
Those are points which I doubt - it's clearly not expressive enough, and there're safer languages either. Is there niche for it? I'm on a fence with popcorn. But as I look to it, I see things which I consider "mistakes". And I love to talk about mistakes!
> And I'm sorry, too, but I would say it's an example of Zig's exceptionally great design at this stage.
Expectedly, I don't buy this "worse is better" argument either. It's not good when you annotate a simple call and it turns from a simple call into an ugly mess. It's not rocket science to come with a syntax which would avoid that. If Zig language creators didn't do that so far, that's exactly what I call "not enough good faith went into Zig design".
Your appendix of "so far" is accepted - keep up the great work!
But that "whole new language" is probably smaller than just AST macros for C. And C's problems aren't solved just by fixing macros (I think AST macros are a horrible feature in almost any language that isn't a Lisp; I see them as a sign that the language designers just gave up).
> Undefined behavior comes from the fact that C is machine-independent assembler
True, but that's almost never a valuable thing these days; you lose portability and get little in return other than a somewhat smaller compiler.
> it's clearly not expressive enough
It's at least as expressive as any other low-level language. Any C++/Rust program -- with generics, concepts, destructors, async, traits, macros -- could be translated to an equivalent Zig program that's at worst no longer than some (small) constant multiple of the original. That's not true for C (at least not without hurting performance).
> and there're safer languages either
Low-level? Not so sure. The goal is a language that makes it easy to write correct programs, not "a safe language". I'm not sure there are languages that do that better.
> I don't buy this "worse is better" argument either
It's an "it's just better" argument. Good design is not about picking arbitrary things and making them more convenient, but about spending a certain budget in a way that yields a good gestalt.
> It's not rocket science to come with a syntax which would avoid that.
Sure, but you can add that syntax at any time. It's not urgent. It's best to see if you could perhaps generalise it in some way and get a better return, or maybe invest your complexity budget more wisely elsewhere. I doubt compiler directives make up more than 0.1% of a program.
> If Zig language creators didn't do that so far, that's exactly what I call "not enough good faith went into Zig design".
I've been programming for ~30 years, and aside from Scheme -- maybe -- I don't think I've ever encountered a better-designed language than Zig. Of course, this perception is subjective.
Zig offers a radical design. It seeks to be as simple as C — which is particularly important in low-level programming for both portability [1] and humans and machine analysis — while also giving you safety and high expressivity. Obviously, radical design means doing things differently.
Zig rejects any kind of implicitness; all calls must appear as calls. This means no operator overloading, no destructors, and no magical traits. It does so, however, without giving up on expressivity by using other mechanisms.
All low-level programming languages suffer from low abstraction. That comes with the territory. By that I mean that implementation details (especially around memory management) are hard to hide. Changing those details in some component often require changing the clients of that component as well. But C++ and Rust have a design philosophy that tries to hide this intrinsic quality of low-level programming by making the final code appear on the page as if it has abstraction capabilities similar to high-level languages. Of course, that illusion breaks as soon as you try to change code, and it's debatable whether this design helps or harms program comprehension. Zig rejects the C++ philosophy in favour of a brand new, and pretty revolutionary one, that reimagines how low-level programming is done. Unlike Rust, Zig isn't a cleaned-up C++ with a few extra tricks, but it isn't a new C, either. It's something completely different.
You might prefer Zig's design for this domain (as I do) or you might prefer the more traditional C++ design, but the great thing is that Zig is so simple and easy to learn that it's easy to try and find out.
[1]: Consider what it would take to port C++ (or a C++-like language) to new microcontroller you build. You would either need to port LLVM or an extremely complex compiler — a huge undertaking. This is why C (well, there's a tiny bit of Ada, too) still reigns supreme even in domains where correctness is of utmost importance: https://youtu.be/uqan23518Yc?t=632