Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Partial evaluation has been quite well known at least since 1943 and Kleene's Smn proof. It has since been put to use, in various forms, by quite a few languages (including C++ in 1990, and even C in the early seventies). But the extent and the way in which Zig specifically puts it to use -- which includes, but is not limited to, how it is used to replace other features that can then be avoided (and all without macros) -- is unprecedented.

Pointing out that other languages have used partial evaluation, sometimes even in ways that somewhat overlap with Zig's use, completely misses the point. It's at least as misplaced as saying that there was nothing new or special about iPhone's no-buttons design because touch screens had existed since the sixties.

If you think Zig's comptime is just about running some computations at compile time, you should take a closer look.



I'd like to see an example! as I cannot think of one.


An example of what?


Not OP, but I guess based on your comment:

> But the extent and the way in which Zig specifically puts it to use -- which includes, but is not limited to, how it is used to replace other features that can then be avoided (and all without macros) -- is unprecedented.

That MrWhite wanted to knkw an example of Zig's comptime that is not merely a "macro", rather the usage as a replacement of other features (I guess more complex..)

PS just interested in zig, I'd like some pointer to these cool feature :)


An unprecedented use.


Ok, so a primary goal of comptime in Zig is to avoid needing certain specialised features while still enjoying their functionality, in particular, generics, interfaces, and macros. I'm not aware of any language that has been able to eliminate all of these features and replace them with a simple, unified partial evaluation mechanism.

In addition, there's the classic example of implementing a parameterised print (think printf) in Zig. This is a very basic use of comptime, and it isn't used here in lieu of generics or of interfaces, but while there may be some language that can do that without any kind of explicit code generation (e.g. macros), there certainly aren't many such examples: https://ziglang.org/documentation/0.15.2/#Case-Study-print-i...

But the main point is that the unprecedented use of partial evaluation is in having a single unified mechanism that replaces generics, interfaces, and macros. If a language has any one of them as a distinct feature, then it is not using partial evaluation as Zig does. To continue my analogy to the novel use of a touchscreen in the iPhone, the simplest test was: if your phone had a physical keypad or keyboard, then it did not use a touchscreen the way the iPhone did.


D's `write` function is generic:

    write(1,2,"abc",4.0,'c');
write is declared as:

    void write(S...)(S args) { ... }
where `S...` means an arbitrary sequence of types represented by `S`. The implementation loops over the sequence, handling each type in its own individual fashion. User defined types work as well.


If D has a separate feature for one of: generic types, interfaces and macros, then obviously it doesn't use partial evaluation similarly to how Zig does. It seems to me that it has all three: templates, interfaces, and string mixins. So if Zig uses its unified partial evaluation feature to eliminate these three separate features, why bring up D, which clearly does not eliminate any one of them?

It's like saying the the iPhone design wasn't novel except for the fact that prior art all had a keypad. But the design was novel in that it was intended to eliminate the keypad. Zig's comptime feature is novel in that it exists to eliminate interfaces, generics, and macros, and you're bringing up a language that eliminates none of them.

So D clearly isn't an example, but perhaps there's some other language I haven't heard of. Just out of curiosity, can a printf in D not only check types at compile time but also generate formatting code while still allowing for runtime variables and without (!!!) the use of string mixins? Like I said, it's possible there's precedent for that (even though it isn't the distinguishing feature), and I wonder if D is that. I'm asking because examples I've seen in D either do use string mixins or do not actually do what the Zig implementation does.


If you have an example of what you're talking about, I'd like to see it.


An example of Zig not having generics, interfaces, and macros? I don't understand.


@pron If all you mean is there is more syntax to D than to zig to achieve same/similar thing then you may be a bit aggresive on how you communicate it.


It's not about more syntax, it's about design, and how Zig was the first to use partial evaluation to do away with several, rather common, features.

It's like how the novelty of the iPhone's touchscreen design was in not having a keypad, or that the novelty of the spork wasn't in inventing the functionality of either the spoon or the fork, but in having a single utensil that performs both. The more important aspect isn't the functionality but the design. I'm not saying you need to like any of these designs, but they are novel.

Saying that you could have a similar functionality by other means misses the point as much as saying that there's nothing special about a spork because if you have a spoon and a fork, then you have the same functionality. But you still don't have a spork.

You could, then, ask what the point of the novel design is. Well, in some languages you have generics and interfaces and compile-time expressions, but because none of these is general and powerful enough, so you also have macros. Macros are very powerful - perhaps too powerful - but they are difficult to understand, so they're used sparingly even if they can subsume other functionality.

Zig has shown that you can do almost anything you would reasonably want to do with macros with partial evaluation that has access to reflection. That wasn't obvious at all. And because that feature was not only powerful enough to subsume other features and make them redundant, but also very simple and easy to understand, it ended up with a design that is both minimal and easy to read (which is important for code reviews) but also highly expressive. Again, you don't have to like this rather minimalistic design, but it is novel.


> Zig was the first to use partial evaluation to do away with several, rather common, features

Please show an example of Zig partial evaluation.


I posted a few examples below: https://news.ycombinator.com/item?id=45865028


The partial evaluation you mentioned.


I'm still not sure what exactly you're asking, but the implementation of print linked above (https://ziglang.org/documentation/0.15.2/#Case-Study-print-i...) typically requires some kind of syntactic macros in other lanugages as does something like "innerParse" here (https://ziglang.org/documentation/0.11.0/std/src/std/json/st...), this (https://ziglang.org/documentation/0.15.2/#Generic-Data-Struc...) would typically require some kind of a separate generics or templates feature in other languages, and to see how comptime replaces interfaces, search for "formatType" here: https://marcelgarus.dev/comptime.

Again, the novel use of partial evaluation in Zig is that it eliminates generics, interfaces, and macros. Any language that has one or more of these features does not have this novel design.


print is a fairly complicated case, as it has to deal with all kinds of different types.

I mean a simple example. Just to illustrate the concept. Like the examples I provided here:

https://news.ycombinator.com/item?id=45859669


If you scroll a bit up on the page from the print example, you'll see more introductory stuff: https://ziglang.org/documentation/0.15.2/#Introducing-the-Co...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: