4 ms·
Consider the domain Zig targets -- low-level programming -- and other languages targeting it: C, C++, Ada and Rust. The first is very simple but severely lacks
by pron 6y ago
Consider the domain Zig targets -- low-level programming -- and other languages targeting it: C, C++, Ada and Rust. The first is very simple but severely lacks in both expressive power and safety, and the other three would all easily make any list of the top five most complex programming languages in the history of software; they're byzantine temples for those who worship at the altar of accidental complexity.
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 https://youtu.be/uqan23518Yc?t=632
- eklavya 6y agoWhat would be accidentally complex about Rust? Sure, if you don't provide the static guarantees that Rust does (and only Rust provides AFAIK), you can be a lot simpler :) 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!!
- friend-monoid 6y agoTry compiling a program with nostd and nocore - try targeting a weird platform, like a small embedded device. You immediately find out how many hidden layers there are to Rust, it’s borderline annoying. Rust is an amazing language, but stuff like mem transmute and I don’t know - it’s been a while now - just trips you up. It’s possible that I just don’t “get” rust, but maybe that’s also the problem. Zig is so easy it’s hard to get wrong. Zig favours readability and understandability over everything else. I can easily grasp complex questions like “will this overflow my very limited call stack” in Zig - it’s harder in Rust (for me anyway).
- deleted 6y ago[deleted]
- pron 6y agoRust, like C++ if not more, elevates certain technical details like lifetime, static vs. dynamic dispatch, partial evaluation, and sequential composition ("default" vs. async) to multiple layers of syntactic constructs (types, generics, macros). That focuses the language on accidental complexity, although some people do find that C++ design philosophy appealing (I would expect some high correlation between people who like Scala and people who like Rust as I would between those who don't like either). Of course, it's a matter of personal aesthetics, but I think that style is misapplied for low-level domains, putting a lot of effort into a veneer of high abstraction without actually providing it (you still have to think about these aspects, as you do in all low-level languages, and, much more importantly, it still requires changing client code when details change, as in all low-level languages -- i.e. changing a Rust program is not like changing a Scala program), doing, IMO, more harm than good. 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.
- pfalcon 6y ago> It seeks to be as simple as C 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/#call https://ziglang.org/documentation/master/#call 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: /*pragma:noinline*/ collectNoInline(gc);
- pron 6y ago> Comparing to really-simple C, it's full of arcane stuff. 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.
- pfalcon 6y ago