upvote
I don't think there is a standardized meaning of 'low-level'. I think a useful definition is that a low-level language controls more/is explicit about more properties of execution.

So zig/c/c++/rust all have ways to specify when and where should allocations happen, as well as memory layout of objects.

Expressivity is a completely different axis on which these low-level languages separate. C has ultra-low expressivity, you can barely create any meaningful abstraction there. Zig is much better at the price of remarkably small amount of extra language complexity. And c++ and rust have a huge amount of extra language complexity for the high expressivity they provide (given that they have to be expressive even on the low-level details makes e.g. rust more complex as a language than a similar, GC-d language would be, but this is a necessity).

As for this particular case, I don't really see a level difference here, both languages can express the same memory layout here.

reply
> Option<T> is trivial. But Tuple<N>? Parameterizing a struct by layout, AoS vs SoA? Compile time state machines? Parser generators? Serialization? These are likely where Zig would shine compared to the others.

I don't see how any of that becomes easier in the Zig case. It's just extra syntactic ceremony. The Rust version conveys the exact same information.

reply
It’s precisely not syntactic ceremony. It’s normal Zig running at compile time in which you can program types as values. In Rust (and most other languages) all you get is a highly abstract DSL:

Foo<T> where for<‘a> T: Bar<‘a, baz(): Send>

Information dense, but every new feature needs language design work. Zig lets you express arbitrary logic, loops, conditionals, etc. It’s lower level of abstraction than a type constraints DSL.

For example, adding “the method in this trait is Send” to Rust’s DSL took a whole RFC and new syntax for Rust. The Zig equivalent could be implemented with an if statement on a type at comptime.

Or how about the transformation of an async function into a state machine. Years of work, deep compiler integration, no way to write such transforms yourself. Same with generators, which still aren’t stable. I’d really like to be able to write these things like any other program.

If you don’t want or need to express things at this lower level of abstraction, fair, same reason most people stick to scripting languages and don’t think about memory layout. But “extra ceremony” is really underselling it.

reply