5 ms·
I 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
by haberman 6y ago
I 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.
- jeltz 6y agoTow issues I have noticed with Zig: not as good type signatures for functions and not as good error messages. I am not sure if those are fundamental issues with Zig's apporach or if they can be fixed with more work.
- vram22 6y agoCan you elaborate a bit on the first issue?
- jeltz 6y agoTake for example the definition of floor(), how would an IDE or documentation generator see which types are supported? This is just imperative code which is executed at compile time and at least to me it is not obvious how to interpret it when generating the documentation. On the other hand in Rust it is almost always easy to see which types can be used where. pub fn floor(x: anytype) @TypeOf(x) { const T = @TypeOf(x); return switch (T) { f16 => floor16(x), f32 => floor32(x), f64 => floor64(x), f128 => floor128(x), else => @compileError("floor not implemented for " ++ @typeName(T)), }; }
- haberman 6y agoThis seems reasonable to me. It seems comparable to the following in C++: template <class T> T floor(T x) { /* ... */ } I think a documentation generator could display your Zig signature verbatim and a user could make sense of that.
- pron 6y agoNot only was it not "more popular," I am not aware of even research languages taking the idea of general-purpose partial evaluation not through syntax macros to the same lengths as Zig (although that doesn't mean there weren't any). It's possible that no one had thought of that, perhaps because type systems, while known to be possibly considered as a form of partial evaluation, are generally treated and studied as a completely separate concept: partial evaluation is a compilation technology while types are part of the theory.
- haberman 6y ago> I am not aware of even research languages taking the idea of general-purpose partial evaluation not through syntax macros to the same lengths as Zig One that comes to mind is Terra: http://terralang.org/ http://terralang.org/ In retrospect Terra seems a clear precursor to Zig (though I don't know if it was a direct influence).
- pron 6y agoI've heard of Terra, but I didn't know it had predated Zig by a couple of years; thought they were introduced at about the same time. And yes, there are certainly similarities, although Terra thinks of itself as two interoperating languages, while in Zig there is just one (although there are things you can only do in comptime so perhaps it's more of a difference in perspective).
- throwaway17_17 6y agoI’m not clear on what you define syntax macros, but the compile time evaluation that is present in Zig (based on the example and documentation I’ve seen) are an almost direct implementation of the multistage computation research done late 90s-mid 00s. The papers and such are typically ML based (with a caveat for the early Template Haskell paper in 02) and the underlying constructs of MetaML are very close to what Zig implements. All this work is retroactively semantically underpinned by Rowan Davies and Frank Pfenning work on Modal S4 logic. I don’t know if Andy based Zig on this research, but if he didn’t, the convergence toward the same theory is a great thing to see. My current work on a visual programming compatible language also uses this strategy for meta programming, so I’m very familiar with the academic literature. It certainly seems that Zig got this right and is doing well implementing it in a way that is usable and understandable.