Comment by pron

5 years ago

Zig's design is so radical, that it completely rethinks how low-level programming can and should be done, rather than improve on one of the existing low-level programming philosophies (C or C++'s). That the result is such a simple and easy-to-learn language that, despite being so radical, doesn't feel foreign is truly an accomplishment.

> In particular, that much of the complexity I’d unconsciously attributed to the domain — “this is what systems programming is like” — was in fact a consequence of deliberate Rust design decisions.

I also thought that, and, to be fair to Rust, it is following the tradition of C++ and Ada, two low-level languages that would also easily make the top five most complex languages in history alongside Rust. Until Zig showed up, I, and I think many others, didn't believe that an expressive low-level language could be made so simple, certainly not one that values safety.

What do you find radical about Zig?

I like Zig, but can't see anything particularly revolutionary about it's design.

The features mostly an evolution of concepts found in languages like D or Nim.

Between the two, Rust is much more revolutionary. Although Rust, of course, was also heavily inspired by research languages that came before.

There's very little happening in CS that hasn't already been conceptualized in the 50-70ies.

  • > What do you find radical about Zig?

    Personally, I find the "bring your own allocator" philosophy to be pretty radical. Yeah, other systems programming languages can facilitate additional allocators beyond "the" allocator for the language's runtime, but Zig seems to optimize for that case, which makes it a lot more intuitive from a learning perspective (no more guessing about where the memory lives). Even Rust (last I checked) defaults to assuming some global one-size-fits-all allocator.

    There's also Zig's flavor of compile-time code / metaprogramming. It's probably less powerful than Rust's macros, but I feel like it's a lot cleaner and intuitive, and I'd argue that being able to run ordinary Zig code at compile time is powerful enough of a feature for Zig's use cases. Ultimately, it's a nice happy medium between full-blown metaprogramming (like in Lisp and - from what I understand - Rust) v. preprocessing (like in C/C++).

    And yeah, I'm sure there's plenty of prior art for everything that Zig does, but I don't know of any other languages that combine these things in such a simple and intuitive and principle-of-least-astonishment-friendly way Zig does.

  • Zig's main feature is what it doesn't have, and the languages you mentioned don't have that feature.

    Other languages also have more-or-less general partial evaluation constructs, but they're not revolutionary because they didn't realise they can express traditional constructs in terms of partial evaluation. Zig is revolutionary in that its simple partial evaluation construct replaces generics/templates, typeclasses/concepts/traits, macros and conditional compilation. The result is something that is consistent, extremely powerful, and yet exceptionally simple.

    • Hacker news has a really hard time valuing simplicity. I think it’s an egotistical thing: I’m smart so I don’t need a simple language.

      What people miss is that a simple a language allows you to apply your smarts to solving the actual problems in front of you instead of puzzling over language features. You can only handle so much cognitive load at once, and ideally the vast majority of that should be devoted to whatever problem you’re solving, not to the language itself.

      Ironically, this fact is the same fact that makes complex languages more fun for hobbyists. There’s simply more to explore, and to try, and to solve, when your object isn’t building a product but instead playing with a language. It’s a different purpose, but people very rarely acknowledge this fact, likely because they’d rather pretend their purposes are clearly mechanical and business oriented. It’s ok to just want to have fun sometimes.

      7 replies →

    • As mentioned in my other (wall of text) comment, that's not strictly beneficial.

      It forces you to implement a lot of logic in "userspace" that other languages do for you automatically.

      Complexity for certain abstractions moves from the language to user code, at the expense of consistency, cohesion, totality and (auto-generated) documentation.

      It will be interesting to see how things play out for Zig once the ecosystem grows a little and libraries appear, but there are very significant downsides to this approach.

      7 replies →

    • > Zig is revolutionary in that its simple partial evaluation construct replaces generics/templates, typeclasses/concepts/traits, macros and conditional compilation.

      This is what C++98 did, except they called their one true comptime evaluation construct "templates", and they did it by accident. There's a reason why Rust introduced generics and typeclasses separately: C++98 templates as bespoke comptime evaluation was a disaster, and this was clear already in the C++ community.

      11 replies →

  • The approach to arbitrary compile-time execution seems like a particularly novel feature.

    • D, Nim, and Haxe had it for quite some time (Along with Jai, which is yet unreleased to the public), although you can argue that Zig’s implementation is conceptually the simplest (it has merged compile time semantics with generic types in a unified way).

      8 replies →

I like Zig a lot, but I'm concerned that it's yet another language that leaves memory management up to the developer.

For example, Zig does not appear to have any concept of lifetimes, and does not enforce single mutable ownership. As I understand it, Zig does not have RAII, either, so cleanup (with "defer", etc.) is also left as an exercise for the programmer. Zig has arenas, allowing quick cleanup, but seems pretty bare-bones otherwise.

(I was relieved to see that Zig does not allow unchecked null pointers.)

  • In very low level programming, we probably want more fine grained control, and specialized code tends to use specialized arena allocators anyway.

    If I am to write a browser engine, I'd choose rust, to write an embedded OS I'd choose zig.