4 ms·
It's not novel. D pioneered compile time function execution (CTFE) back around 2007. The idea has since been adopted in many other languages, like C++. One thi
by WalterBright 2y ago
It's not novel. D pioneered compile time function execution (CTFE) back around 2007. The idea has since been adopted in many other languages, like C++.
One thing it is used for is generating string literals, which then can be fed to the compiler. This takes the place of macros.
CTFE is one of D's most popular and loved features.
- az09mugen 2y agoA little bit out of context, I just want to thank you and all the contributors for the D programming language.
- WalterBright 2y agoThat means a lot to us. Thanks!
- msteffen 2y agoIf I understand TFA correctly, the author claims that D’s approach is actually different: https://matklad.github.io/2025/04/19/things-zig-comptime-wont-do.html#:~:text=For%20example%2C%20D%20mixins%20work%20that%20way https://matklad.github.io/2025/04/19/things-zig-comptime-won... “In contrast, there’s absolutely no facility for dynamic source code generation in Zig. You just can’t do that, the feature isn’t! [sic] Zig has a completely different feature, partial evaluation/specialization, which, none the less, is enough to cover most of use-cases for dynamic code generation.”
- WalterBright 2y agoThe partial evaluation/specialization is accomplished in D using a template. The example from the link: fn f(comptime x: u32, y: u32) u32 { if (x == 0) return y + 1; if (x == 1) return y * 2; return y; } and in D: uint f(uint x)(uint y) { if (x == 0) return y + 1; if (x == 1) return y * 2; return y; } The two parameter lists make it a function template, the first set of parameters are the template parameters, which are compile time. The second set are the runtime parameters. The compile time parameters can also be types, and aliased symbols.
- msteffen 2y agoHere is, I think, an interesting example of the kind of thing TFA is talking about. In case you’re not already familiar, there’s an issue that game devs sometimes struggle with, where, in C/C++, an array of structs (AoS) has a nice syntactic representation in the language and is easy to work with/avoid leaks, but a struct of arrays (SoA) has a more compact layout in memory and better performance. Zig has a library to that allows you to have an AoS that is laid out in memory like a SoA: https://zig.news/kristoff/struct-of-arrays-soa-in-zig-easy-in-userland-40m0 https://zig.news/kristoff/struct-of-arrays-soa-in-zig-easy-i... . If you read the implementation (https://github.com/ziglang/zig/blob/master/lib/std/multi_array_list.zig https://github.com/ziglang/zig/blob/master/lib/std/multi_arr...) the SoA is an elaborately specialized type, parameterized on a struct type that it introspects at compile time. It’s neat because one might reach for macros for this sort of the thing (and I’d expect the implementation to be quite complex, if it’s even possible) but the details of Zig’s comptime—you can inspect the fields of the type parameter struct, and the SoA can be highly flexible about its own fields—mean that you don’t need a macro system, and the Zig implementation is actually simpler than a macro approach probably would be.
- WalterBright 2y agoD doesn't have a macro system, either, so I don't understand what you mean.
- msteffen 2y agoIIUC, it does have code generation—the ability to generate strings at compile-time and feed them back into the compiler. The argument that the author of TFA is making is that Zig’s comptime is a very limited feature (which, they argue, is good. It restricts users from introducing architecture dependencies/cross-compilation bugs, is more amenable to optimization, etc), and yet it allows users to do most of the things that more general alternatives (such as code generation or a macro system) are often used for. In other words, while Zig of course didn’t invent compile-time functions (see lisp macros), it is notable and useful from a PL perspective if Zig users are doing things that seem to require macros or code generation without actually having those features. D users, in contrast, do have code generation. Or, alternatively, while many languages support metaprogramming of some kind, Zig’s metaprogramming language is at a unique maxima of safety (which macros and code generation lack) and utility (which e.g. Java/Go runtime reflection, which couldn’t do the AoS/SoA thing, lack) Edit Ok, I think Zig comptime expressions are just like D templates, like you said. The syntax is nicer than C++ templates. Zig’s “No host leakage” (to guarantee cross-compile-ability) looks like the one possibly substantively different thing.
- baazaa 2y agothat's a comically archaic way of using the verb 'to be', not a grammatical error. you see it in phrases like "to be or not to be", or "i think, therefore i am". "the feature isn't" just means it doesn't exist.
- CRConrad 2y agoDamn, beat me by half a day.
- sixthDot 2y agoSure, CTFE can be used to generate strings, then later "mixed-in" as source code, but also can be used to execute normal functions and then the result can be stored in a compile-time constant (in D that's the `enum` storage class), for example generating an array using a function literal called at compile-time: enum arr = { return iota(5).map!(i => i * 10).array; }(); static assert(arr == [0,10,20,30,40]);
- CRConrad 2y ago> the feature isn’t! [sic] To be, or not to be... The feature is not. (IOW, English may not be the author's native language. I'm fairly sure it means "The feature doesn't exist".)
- Someone 2y ago> D pioneered compile time function execution (CTFE) back around 2007 Pioneered? Forth had that in the 1970s, lisp somewhere in the 1960s (I’m not sure whether the first versions of either had it, so I won’t say 1970 respectively 1960), and there may be other or even older examples.
- WalterBright 2y agoTrue, but consider that Forth and Lisp started out as interpreted languages, meaning the whole thing can be done at compile time. I haven't seen this feature before in a language that was designed to be compiled to machine code, such as C, Pascal, Fortran, etc. BTW, D's ImportC C compiler does CTFE, too!! CTFE is a natural fit for C, and works like a champ. Standard C should embrace it.
- Someone 2y agoNitpick: Lisp didn’t start out as an interpreted language. It started as an idea from a theoretical computer scientist, and wasn’t supposed to be implemented. https://en.wikipedia.org/wiki/Lisp_(programming_language)#History https://en.wikipedia.org/wiki/Lisp_(programming_language)#Hi...: "Steve Russell said, look, why don't I program this eval ... and I said to him, ho, ho, you're confusing theory with practice, this eval is intended for reading, not for computing. But he went ahead and did it. That is, he compiled the eval in my paper into IBM 704 machine code, fixing bugs, and then advertised this as a Lisp interpreter, which it certainly was. So at that point Lisp had essentially the form that it has today”
- amszmidt 2y agoSteve Russell comment is about writing the actual interpreter for Lisp, so the comment is correct on that Lisp started out as an interpreted language, and even mentions that in the comment that you quote. The interpreter (i.e. Lisp READ-EVAL-PRINT loop) was written in IBM 704 machine code, which just was a reimplementation of the EVAL function as JMC described it in his paper. The part that "wasn't supposed to be implemented" was about the form of Lisp, M-expressions vs. S-expressions not Lisp it self. Which was supposed to be implemented as a programming system from day one.
- throwawaymaths 2y agoYou're missing the point. If anything D is littered with features and feature bloat (CTFE included). Zig (as the author of the blog mentions) is more than somewhat defined by what it can't do.
- WalterBright 2y agoI fully agree that the difference is a matter of taste. All living languages accrete features over time. D started out as a much more modest language. It originally eschewed templates and operator overloading, for example. Some features were abandoned, too, like complex numbers and the "bit" data type.
- pron 2y agoIt is novel to the point of being revolutionary. As I wrote in my comment, "the novelty isn't in the feature itself, but in the place it has in the language". It's one thing to come up with a feature. It's a whole other thing to position it within the language. Various compile-time evaluations are not even remotely positioned in D, Nim, or C++ as they are in Zig. The point of Zig's comptime is not that it allows you to do certain computations at compile-time, but that it replaces more specialised features such as templates/generics, interfaces, macros, and conditional compilation. That creates a completely novel simplicity/power balance. If the presence of features is how we judge design, then the product with the most features would be considered the best design. Of course, often the opposite is the case. The absence of features is just as crucial for design as their presence. It's like saying that a device with a touchscreen and a physical keyboard has essentially the same properties as a device with only a touchscreen. If a language has a mechanism that can do exactly what Zig's comptime does but it also has generics or templates, macros, and/or conditional compilation, then it doesn't have anything resembling Zig's comptime.
- WalterBright 2y ago> Various compile-time evaluations are not even remotely positioned in D, Nim, or C++ as they are in Zig. See my other reply. I don't understand your comment. https://news.ycombinator.com/item?id=43748490 https://news.ycombinator.com/item?id=43748490
- pron 2y agoThe revolution in Zig isn't in what the comptime mechanism is able to do, but how it allows the language to not have other features, which is what gives that language its power to simplicity ratio. Let me put it like this: Zig's comptime is a general compilation time computation mechanism that has introspection capabilities and replaces generics/templates, interfaces/typeclasses, macros, and conditional compilation. It's like that the main design feature of some devices is that they have a touchscreen but not a keyboard. The novelty isn't the touchscreen; it's in the touchscreen eliminating the keyboard. The touchscreen itself doesn't have to be novel; the novelty is how it's used to eliminate the keyboard. If your device has a touchscreen and a keyboard, then it does not have the same design feature. Zig's novel comptime is a mechanism that eliminates other specialised features, and if these features are still present, then your language doesn't have Zig's comptime. It has a touchscreen and a keyboard, whereas Zig's novelty is a touchscreen without a keyboard.