3 ms·
Like a modern C with lessons learned. Instead of macros it uses Zig itself to execute code at runtime (comptime). Custom allocators are the norm. No hidden cont
by ManBeardPc 1y ago
Like a modern C with lessons learned. Instead of macros it uses Zig itself to execute code at runtime (comptime). Custom allocators are the norm. No hidden control flow, everything is very explicit and easy to follow.
But it’s not only the language itself, it is also the tooling around it. Single unit of compilation has some nice properties, allowing to support colorless async. Fast compile times. Being able to use existing C code easily and having optimization across language boundaries. Cross compilation out of the box. Generally caring for performance in all aspects.
So for me it is a better C, low-level but still approachable and not having so much cruft.
- adgjlsfhk1 1y agoTo be clear, the problem with C isn't macros, but text based macros. Syntax based macros are really good (as shown by Lisp and friends)
- jeremyjh 1y agoTo be clear, we all know GP is talking about C macros.
- ManBeardPc 1y agoNot only being text based but also having another separate language is problematic. Rust also has powerful declarative macros but it is it’s own language. Procedural macros and crabtime are imho a bit better for more complex cases as you write Rust.
- pron 1y agoAST macros are very powerful. As to them being "good", that's debatable. They have advantages but also disadvantages. For one, they operate on syntax, so they're a separate metalanguage and not so pleasant to debug. For another, they are referentially opaque (i.e. when passed different expressions with the same meaning, they can produce different results), which makes them powerful but also mysterious. What's interesting about Zig's comptime is that while it's strictly less powerful than AST macros, it can do a lot of what macros can do while not being a metalanguage - just Zig.
- wyager 1y ago> with lessons learned A very small subset of possible lessons that could have been learned...
- zahlman 1y ago> Instead of macros it uses Zig itself to execute code at runtime (comptime). Nice. FWIW, I have a vague PL design in my head that does this despite being a much higher-level language. (For that matter, I think of my idea much as "like a modern Python with lessons learned".) Point being I definitely think this is a good idea. To my understanding, the things actually called "macros" in Lisp also do this. > Custom allocators are the norm. On the other hand, this doesn't sound to me like an upside. Of course it's fine and well if it's easy to do this. But hopefully you'd prefer not to have to... ? > No hidden control flow, everything is very explicit and easy to follow. What sort of hidden control flow do you see in C? (Are modern code bases using setjmp/longjmp in new code?) I would have thought that C++ is where that really started, via exceptions. But I also don't think most programmers see that as problematic for understanding the code. > Single unit of compilation has some nice properties, allowing to support colorless async. Would appreciate some explanation of the theory here. Though it does occur to me that the languages I can easily think of with "coloured" async also don't exactly statically link everything all the time. Also, how does all of this compare to Rust, in your view?
- Cloudef 1y ago> On the other hand, this doesn't sound to me like an upside. Of course it's fine and well if it's easy to do this. But hopefully you'd prefer not to have to... ? Why wouldn't you? You can often make your code simpler and more performant by using certain allocation strategy rather than relying on global allocator. Malloc/Free style strategy is also very error prone with complex hierarchical data structures where for example arena allocation can tie the whole lifetime to a single deallocation. > Would appreciate some explanation of the theory here. Though it does occur to me that the languages I can easily think of with "coloured" async also don't exactly statically link everything all the ti Async is moot point, it does not exist in zig right now, it used to but it was removed. There are plans to reintroduce it back, but using async as any sort of benefit for zig is not being honest.
- ManBeardPc 1y agoRegarding async I kind of agree with you right now, but the new design is there and currently getting implemented. If you don’t believe it will work out or need to use async right now sure, use something else. It is not a stable language yet and very much WIP. I don’t think it’s dishonest to write about something that has a design and is worked on right now with a realistic chance of working out.
- vlovich123 1y agoI’m not sold that they’ve actually solved the coloring problem vs given it a different syntax.
- metaltyphoon 1y ago> Like a modern C with lessons learned. Yet no string types. So lessons not so well learned. Zig does remove many warts in C.
- ManBeardPc 1y agoIt has proper arrays and slices, even being able to define a sentinel value in the type system, so you know when it is a C string or a slice with a specific size with arbitrary values. Strings can become a problem if you need another encoding than the chosen one. Then you start to use byte slices anyway. You need to allocate a new one if you want to change just a part of it. Safer yes, but can produce unwanted overhead and you have to duplicate many APIs for strings and byte arrays as it is the case in Go.
- pjmlp 1y agoMany of those warts were already not present in other systems languages predating C, and others of similar age.
- user____name 1y agoIt feels like C but raised with Java as its strict stepfather.
- MangoToupe 1y agoI've seen the custom allocators mentioned many times as central to the value proposition. Do the allocators shipped with the standard library compose the system allocator, or are they completely distinct from the *alloc family shipped as part of libc?
- ManBeardPc 1y agoYou can ofc use the *alloc from libc if you want. Otherwise there are different ones in the standard library, ArenaAllocator wraps another allocator, FixedBufferAllocator uses a given byte slice. I recommend to take a look at https://ziglang.org/documentation/master/std/#std.heap https://ziglang.org/documentation/master/std/#std.heap to get an overview.