I found this claim a bit strange. do people actually use metaprogramming in Zig a lot?
I found this claim a bit strange. do people actually use metaprogramming in Zig a lot?
IMO AST Macros are an even bigger problem than text substitution. Debugging metaprogramming of any kind past a certain point of complexity is a royal pain in the ass (even in a Lisp, Forth or Prolog), but AST explorers are next to useless for complicated logic problems that involve needle in a haystack searches of side effects. If you're dealing with a large AoS of heterogeneous SoAs which influence each other to shuffle around, and most of the related code and the structures themselves are generated via AST macros, you better be really comfortable with assembly analysis and debugger scripting.
- It is not distributed across machines. No distributed fault tolerance issues.
- It doesn't run on a resource constrained embedded system, with poor visibility, but in your dev environment.
- It runs in a single thread; no flaky race conditions or deadlocks to debug.
- Its expansion-time performance rarely matters; and it is rarely bogged down with machine dependencies or other low-level stuff.
- It is unit-testable with cases does construct X expanding to construct Y.
I would rather debug a macro than any number of other things I've also debugged.
Where you start to see actual metaprogramming in Zig is in functions like @typeInfo, @alignOf, @offsetOf, which actually let you operate on language constructs (ie: looping over the fields of a struct). This is not extremely out of the ordinary, but it's not done "as much as possible".
Another place that metaprogramming shows up in Zig is code generation using the build system. I've never done this, and I would argue this is usually recommended to be done as little as possible, rather than as often as possible.
Edit: I read the article, and while I think that the author was wrong about Zig pushing metaprogramming "as much as possible", they were fairly accurate in how it is used in the rest of the article, like for serialization. The thing is, most of my programs are not serialization. I use serialization as a means to do other things.
however, it's also a good signal "please review this code to make sure i didn't f it up"
var x: [sqrt(LENGTH)]f32 = undefined
i think calling "instantiating a generic type" meta-programming is weak, since you're not doing any of the metaprogramming yourself, though i would concede that if debugging is the concern there is a point there.same goes for "using std.debug.print"