8 ms·
Neat concept. Exploring the difference between what successfully compiles vs. what won't seems like a great way of getting more familiar with the language. I'
by haberman 6y ago
Neat concept. Exploring the difference between what successfully compiles vs. what won't seems like a great way of getting more familiar with the language.
I've written a little over 1,000 lines of Zig at this point and I really like it. I think its key feature is a rich compile-time imperative programming environment ("comptime"). If you can have full compile-time imperative code execution, you can get a lot of the benefits of more complicated language features (like C++ templates) "for free."
In C++ templates are "a language within a language", but even templates with all their complexity cannot solve all of the problems you might want to solve at compile-time, so C++ has been gradually expanding its compile-time code execution features so that more and more of the language is available at compile-time (constexpr, consteval, etc). Zig jumps straight to the finish line by making most of the language available at compile-time from the outset, and in doing so avoids the need to add the complexity of templates in the first place.
Having "slices" as a first class type feels like a general and powerful solution to the problems that std::string_view and std::span are trying to solve.
I am comparing Zig to C++ a lot, which many Zig fans would probably take exception to as Zig does not aspire to be a better C++, but rather a better C. Indeed many key C++ patterns like RAII are explicitly out of scope. But to me Zig bridges the gap between C and C++ by solving many of the problems that make C feel too spartan without jumping to the incredible complexity of C++.
There are a few things about Zig that give me pause. I've noticed that compile-time feels like a very lazy environment, meaning that functions do not seem to undergo full semantic analysis unless they are called from somewhere. You can write a function that compiles successfully, leading you to believe the function is syntactically and semantically coherent, only to find that when you add an actual call to that function, the compiler now flags errors inside that function. This adds some friction to development, because the act of writing a function is no longer a self-contained activity. Writing the function feels more like sketching it; later when you actually call it you have a new set of compile errors to contend with.
I also miss tools like ASAN to catch memory errors. I'm guessing things like that will come with time.
Overall I feel very positive on Zig.
- fpoling 6y agoZig compile-time evaluation even allows to construct an arbitrary type like a struct with a platform-specific members all using the same core language. This beats even Rust macros and in retrospect I wonder why this not used in other languages? Even Lisp ended up with macros with own sub language instead of making the core language more useful for code generation. Or consider Go attempts at generics. Something like Zig approach will fit it more I think than various generics proposals.
- haberman 6y agoI agree it's an idea that seems so natural in retrospect that I'm also curious why it hasn't traditionally been more popular. One possible reason that comes to mind is that an imperatively-constructed type is harder to statically analyze. But on the other hand, even C++ templates are Turing complete and even C++ parse trees can depend on the output of a Turing-complete evaluation. So it is hard to see what benefit a C++-like template feature is buying in comparison.
- fpoling 6y agoEven Java and Rust ended up with Turing-complete generics.
- bobthebuilders 6y agoJava turing complete generics are an edge case though, and never hit during normal compilation.
- fpoling 6y agoStill the compiler has to deal with that. So one ends up with an interpreter in the compiler for very esoteric and hard to write/read language instead of just embedding an interpreter of a subset of Java. One alleged benefit of Java constrained genetics is that they allow in theory better error messages. Still in complex cases even after over 15 years with genetics in Java the error messages are not that great. Zig to some extend delegates to the compile-time library authors responsibility of producing good error messages. But then the error messages can be improved without waiting for the compiler to improve its reporting heuristics to cover all edge cases.
- bobthebuilders 6y agoIncorrect Java does not have genetics. That is a C++ concept.
- 6y ago
- Hoppetosse 6y agoThe standard library has a General Purpose Allocator that can catch some of the errors that ASAN can, like memory leaks.
- kristoff_it 6y ago> I am comparing Zig to C++ a lot, which many Zig fans would probably take exception to as Zig does not aspire to be a better C++, but rather a better C. I was one of those people that started the idea that Zig should be compared to C more than C++. One day I'll express more clearly what I meant by that, but in the meantime I would say that Zig can and should be compared with C++ too. More generally I think we got to the point where Zig deserves to be analyzed in it's own right and not as a reflection of another language because, among other things, it leads to this kind of misunderstanding: > I've noticed that compile-time feels like a very lazy environment, meaning that functions do not seem to undergo full semantic analysis unless they are called from somewhere. Comptime's lazyness is a necessary feature and not an accident. This is how Zig can avoid having a macro system. More in general the idea is that you are supposed to write tests for your code, which will then ensure your functions get analyzed, and which in turn will produce documentation for your code. This makes testing more core to the development process than it is in other languages. I'm not saying everyone has to like this approach, but if you stop at the comparison with C, you risk missing how the design of Zig is able to spiral into an new and radical programming experience. See for example this Twitch clip from yesterday: https://clips.twitch.tv/RockyLivelyChimpanzeeDoubleRainbow-Pov6fVYDbH1_r-A6 https://clips.twitch.tv/RockyLivelyChimpanzeeDoubleRainbow-P...
- aarchi 6y ago> Comptime's lazyness is a necessary feature and not an accident. This is how Zig can avoid having a macro system. Can you elaborate on lazy analysis replacing the need for macros?
- Quekid5 6y agoI'd appreciate some elaboration on that too. It sounds vaguely similar to SFINAE in C++, but I don't know enough about Zig's compilation model to know for sure. (I'm vaguely familar with Zig from a talk by the creator about 1½ years ago, fwiw.)
- defen 6y agoC macros are lazy, but they also operate at the level of lexical tokens instead of the AST, which means you can use macros to generate C code, but you can't really do it in a way that is guaranteed to be safe. With Zig you can have a function where some or all arguments are marked as "comptime", which means the values for those arguments must be known at compile time. Combined with the fact that types can be used as values at compile time means that you can use Zig to generate Zig functions in a safe way.
- klyrs 6y ago> You can write a function that compiles successfully, leading you to believe the function is syntactically and semantically coherent, only to find that when you add an actual call to that function, the compiler now flags errors inside that function. This happens to me pretty frequently in C++. It won't compile with a syntax error, but if you don't call, say, a templated function, then the compiler simply can't know that the stuff you're doing inside is nonsense. I don't consider this to be friction. I generally know what I've called, and what I haven't. I expect dark code to be bug-ridden placeholders with good intentions.
- lenkite 6y agoThis will be fixed with C++ 20 concepts right ?
- IgorPartola 6y agoOne of the small but really good features of Zig that immediately stood out to me was the fact that there are no implicit function or method calls. my.name will never call a hidden function. As useful as @property is in Python, it really makes it hard to reason about performance of code until you dig all the way through every bit of every class and type.
- vram22 6y agoIs Zig's comptime feature like D's CTFE?