4 ms·
I’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
by throwaway17_17 6y ago
I’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.
- pron 6y agoBy syntax macros I mean expressions that can be referentially opaque, i.e. m(a) and m(b) might have different semantics even though a and b have the same reference. Lisp (and C, and Haskell, and Rust) is referentially opaque while Zig is transparent. Opacity is strictly more expressive, but is harder to understand; Zig strives to be the "weakest" language possible to get the job done. MetaML certainly does seem to be similar to Zig, although the one paper I've now read thanks to your suggestion (https://www.sciencedirect.com/science/article/pii/S0304397500000530 https://www.sciencedirect.com/science/article/pii/S030439750...) does not mention introspection and type functions, and another commenter here suggests that it is, actually, referentially opaque.
- kazinator 6y agoSuppose a and b have the same reference. Zig allows something like { const a = 42; const b = 72; ... } which gives these names new references which they no longer share, in a scope. So the opacity is there in some built-in operators; the only question is whether macros can imitate that.
- ymbeld 6y agoIt doesn’t seem as general as MetaOcaml. Just two-stage evaluation, and without quote and splice.
- pron 6y agoI think Zig's comptime has three interesting features: 1. It is referentially transparent, i.e., unlike Lisp, i.e. nothing in the language can distinguish between `1 + 2` and `3`. This means that the semantics of the language is the same as if everything was evaluated at runtime, and the comptime annotation has no impact on semantics (assuming syntax terms aren't objects and there's no `eval`). 2. It supports type introspection and construction. 3. It doesn't have generics and typeclasses as separate constructs but as applications of comptime. I think 3 is unique to Zig, but I wonder about 1: is it possible in MetaOCaml, as it is in Lisp, C, C++, Rust and Haskell -- but not in Zig! (or, say, Java) -- to write a unit `m`, such that m(1 + 2) is different from m(3)?
- ymbeld 6y agoI don’t know. I think MetaOcaml is strict about inspecting Code terms like Code (1 + 2) and Code 3 (as far as I remember it is not allowed). So no, I don’t think you can distinguish between them.
- throwaway17_17 6y agoI think (again based on examples and docs) that it is actually multistaged. However, this is not apparent because the quote and splice are semi-implicit. The ‘comptime’ keyword is essentially a the quote operator, ie. it produces what is essentially a compile time thunk, lazily capturing the ‘code’ value of the expression defined under the comptime keyword. This thunk is directly analogous to a value of type ‘code a’ in MetaML. Then there is an implicit splice operator in place any time a value defined under comptime is used subsequently. I say it is multistaged because it certainly appears that one can define a comptime variable for some computation and then use that variable in a later comptime definition or expression. So, it looks like a basic data flow analysis to determine dependency is done on the comptime evaluations and those are ordered implicitly. This order would correspond to the more explicit staging syntax of MetaML and the operation semantics that underpin it.