HNHacker News
TopNewBestAskShowJobs

ScottRedig

51 karma · joined January 7, 2025

submissionscomments
ScottRedig··on Why is Zig so cool?
Hello Mr. Bright. I've seen similar comments from you in response to Zig before. Specifically, in the comments on blog post I made about Zig's comptime. I took some time reading D's documentation to try to understand your point (I didn't want to miss some prior art, after all). By the time I felt like I could give a reply, the thread was days old, so I didn't bother.

The parent comment acknowledges that compile time execution is not new. There is little in Zig that is, broad strokes, entirely new. It is in the specifics of the design that I find Zig's ergonomics to be differentiated. It is my understanding that D's compile time function execution is significantly different from Zig's comptime.

Mostly, this is in what Zig doesn't have as a specific feature, but uses comptime for. For generics, D has templates, Zig has functions which take types and return types. D has conditional compilation (version keyword), while Zig just has if statements. D has template mixins, Zig trusts comptime to have 90% of the power for 10% of the headache. The power of comptime is commonly demonstrated, but I find the limitations to be just as important.

A difference I am uncertain about is if there's any D equivalent for Zig having types being expressions. You can, for example, calculate what the return type should be given a type of an argument.

Is this a fair assessment?

ScottRedig··on Zig's comptime is bonkers good
Zig lets you inspect type info (including, eg, function signatures), but it doesn't give you raw access to the AST. There's no way to access the ast of the body of the function. As highlighted by view 0 in my article, I consider this a good thing. Zig code can be read without consideration for which pieces are comptime or not, something that heavy AST manipulation loses.

Though, if you really wanted to do stupid things, you could use @embedFile to load a Zig source file, then use the Zig compiler's tokenizer/ast parser (which are in the standard library) to parse that file into an AST. Don't do that, but you could.

ScottRedig··on Zig's comptime is bonkers good
Fixed, thanks for the report.
ScottRedig··on Zig's comptime is bonkers good
Hi, article author here. I was motivated to write this post after having trouble articulating some of its points while at a meetup, so that's why the goal of this post was focused on explaining things, and not being critical.

So at least address your points here:

* I do agree this is a direct trade-off with Zig style comptime, versus more statically defined function signatures. I don't think this affects all code, only code which does such reasoning with types, so it's a trade-off between reasoning and expressivity that you can make depending on your needs. On the other hand, per the post's view 0, I have found that just going in and reading the source code easily answers the questions I have when the type signature doesn't. I don't think I've ever been confused about how to use something for more than the time it takes to read a few dozen lines of code.

* Your specific example for recursive generic types poses a problem because a name being used in the declaration causes a "dependency loop detected" error. There are ways around this. The generics example in the post for example references itself. If you had a concrete example showing a case where this does something, I could perhaps show you the zig code that does it.

* Type checking happens during comptime. Eg, this code:

  pub fn main() void {
      @compileLog("Hi");
      const a: u32 = "42";
      _ = a;
      @compileLog("Bye");
  }
Gives this error:

  when_typecheck.zig:3:17: error: expected type 'u32', found '*const [2:0]u8'
   const a: u32 = "42";
                  ^~~~
  Compile Log Output:
  @as(*const [2:0]u8, "Hi")
So the first @compileLog statement was run by comptime, but then the type check error stopped it from continuing to the second @compileLog statement. If you dig into the Zig issues, there are some subtle ways the type checking between comptime and runtime can cause problems. However it takes some pretty esoteric code to hit them, and they're easily resolved. Also, they're well known by the core team and I expect them to be addressed before 1.0.

* I'm not sure what you mean by hygiene, can you elaborate?