Hacker News new | ask | show | jobs
by tayistay 1085 days ago
From the article:

  const result = comptime square("hello"); // compile time error: type mismatch
ok, cool. But if the error occurs deep in some hierarchy of comptime calls, do you get the same kind of long errors that you do with C++ templates? Does zig have a way of achieving better ergonomics? One nice thing about generics in Rust and Swift is they are constrained by traits/interfaces so you get a concise error at the call site.
2 comments

This isn't about Zig, but I found that I prefer something similar to concepts over traits/interfaces, as the former are somewhat limited as to what they express.

    /**
     * @checked x & 1 "The input parameter must allow bit operations"
     */
    macro bool is_power_of_2(x)
    {
      return x != 0 && (x & (x - 1)) == 0;
    }
In the example above (disregard the fact that it's placed in the doc comments) we'd get an error if `x & 1` is invalid (doesn't pass semantic checking). This is the simplest possible example. Basically if you pass in a float or a struct you would then get "The input parameter must allow bit operations" rather than a dump of errors from the macro body.

We can imagine other constraints, such as checking the value (if constant) to conform with valid ranges and so on.

This is more of a "contract" style constraint that can be placed directly at the call location, rather than pushing down the check further down into macro body, for example something like this:

    macro bool is_power_of_2(x)
    {
      $assert($checks(x & 1), "The input parameter must allow bit operations");
      return x != 0 && (x & (x - 1)) == 0;
    }
In this example the error would be localized to the macro, which perhaps isn't what we want, even if the compiler is kind enough to tell us where the macro was included.
A good api (like std.debug.print for example) can implement nice compile errors that fail early with readable messages manually at comptime. Still not as convenient as traits though