Zig's comptime isn't like "macros" in Haxe or Rust or Scala or Lisp which transform one AST into another AST. It's just code that runs when the code is compiled, rather than when the resulting binary is run.
This makes it less expressive, but it also means it is easier to learn and use. (It's a lot like C++'s constexpr)
The interesting part comes from recognizing that by making constructs like structs first-class-values in comptime, you can achieve most of the common things that templates, macros, conditional compilation, etc give you, but with a much simpler feature (which is just running code at compile time)
Lisp and Scheme macros are just code that happens to execute at runtime, too. They don't necessarily need to transform the AST, though that's what they're often used for.
Like with Zig, you are limited mostly by what is available in the environment at macro expansion time; unlike Zig, you can do things that generate allocations.
> It's just code that runs when the code is compiled, rather than when the resulting binary is run.
That’s exactly what Haxe macros are. It’s regular Haxe code that runs during compile, and it has access to all Haxe language features and the standard library.
The only special thing about them is that they can directly manipulate the AST before it gets passed on to the compiler for final code generation.
In a sense, they’re like “shaders” for the compiler.
Macros in Lisp during compilation often extend the compile-time environment and another purpose is to register information in the Lisp IDE (record source code, record source locations, ...).
> but with a much simpler feature (which is just running code at compile time)
Common Lisp does that with the EVAL-WHEN construct, which allows to run arbitrary code at compile time.
This makes it less expressive, but it also means it is easier to learn and use. (It's a lot like C++'s constexpr)
The interesting part comes from recognizing that by making constructs like structs first-class-values in comptime, you can achieve most of the common things that templates, macros, conditional compilation, etc give you, but with a much simpler feature (which is just running code at compile time)