Hacker News new | ask | show | jobs
by gw 2118 days ago
I do love how zig's comptime naturally led to generics without extra syntax. But after using nim i'm convinced that macros make even more sense for systems programming. They can even affect performance -- nim's macros can generate types that would be difficult to write by hand.

I also take issue with your statement that zig is "more minimal" since that only applies to the user's perspective -- from the compiler's perspective, macros make a language far more minimal. But i vaguely recall already discussing this distinction with you so i don't want to rehash it.

At any rate i will definitely be paying attention to andrew's progress, he has a really clear vision.

1 comments

> But after using nim i'm convinced that macros make even more sense for systems programming.

Macros are controversial. I love them in Scheme and Clojure, but I wouldn't want them in any language aimed at a larger, more mainstream crowd. At the very least, macros introduce another meta-language to know (and if they're in a language with a complex type-level language like Rust or Haskell then they're a third language within the language), but I think it's a matter of personal aesthetic preference.

> But i vaguely recall already discussing this distinction with you so i don't want to rehash it.

Maybe we did. :)

Look at any sufficiently complex and/or low level C like Linux or FreeRTOS, and C text macros are used significantly. Some of the functionality would be horrible to implement otherwise. Being text based they're a pain, but like @gw, I'd have a hard time seeing a language like Zig without macros making a good low level system language. Maybe a good systems application like Kubernetes, similar to Go's niche, but not system kernels.
The goal isn't to have macros but to be able to do what macros are used for. Zig has found a different and simpler way to do what macros do. comptime gives you generic types, typeclasses/concepts, typesafe printf, conditional compilation and much more, all without macros and with a simpler construct than macros.
After reading your previous comment, I read a bit more about comptime. It does seem to be able to handle most of the cases I could think of wanting macros for, and it is a nice UX in that it's really like "bounded macros" and prevents building arbitrary new semantics. Though thinking on two levels in a given function does seem tricky to me, but perhaps that's just familiarity. Personally, I kind of like having separate macro vs code. Comptime seems like it'd almost be a better fit for Go than their generics proposal.
The beauty of comptime is that, unlike with macros, you don't need to think on two levels. The semantics is the same as if everything were done at runtime. To read a comptime function you can completely ignore the distinction between compilation time and runtime. To write it you need to know that some operations are only available at compile-time.

See my comment here about "Zig' ": https://news.ycombinator.com/item?id=24293611

Perhaps now you see what I meant when I said that Zig's simplicity hides its radical design.

In Nim the equivalent is using a `static:` block, then everything inside has normal Nim syntax but evaluated at compile-time.

You can also do `const a = static(foo(x, y, z))` to force normal function to be evaluated at compile-time and store them in a constants.

Hence you don't need to use macros for compile-time evaluation in Nim just like in Zig. However macros are necessary for AST manipulation.