3 ms·
> being able to reason about functions just from their type signature. This has nothing to do with compile-time execution, though. You can reason about a funct
by jmull 2y ago
> being able to reason about functions just from their type signature.
This has nothing to do with compile-time execution, though. You can reason about a function from its declaration if it has a clear logical purpose, is well named, and has well named parameters. You can consider any part of a parameter the programmer can specify as part of the name, including label, type name, etc.
> There is a good discussion of some issues here: https://typesanitizer.com/blog/zig-generics.html https://typesanitizer.com/blog/zig-generics.html
That's actually not a great article. While I agree with the conclusion stated in the title, it's a kind of "debate team" approach to argumentation which tries to win points rather than make meaningful arguments.
The better way to frame the debate is flexibility vs complexity. A fixed function generics system in a language is simpler (if well designed) than a programmable one, but less flexible. The more flexibility you give a generics system, the more complex it becomes, and the closer it becomes to a programming language in its own right. The nice thing about zig's approach is that the meta-programming language is practically the same thing as the regular programming language (which, itself, is a simple language). That minimizes the incremental complexity cost.
It does introduce an extra complexity though: it's harder for the programmer to keep straight what code is executing at compile time vs runtime because the code is interleaved and the context clues are minimal. I wonder if a "comptime shader" could be added to the language server/editor plugin that puts a different background color on comptime code.
- jasode 2y ago>You can _reason_ about a function from its declaration if it has a clear logical purpose, is well named, and has well named parameters. I think "reason" in gp's context is "compile-time reasoning" as in the compiler's deterministic algorithm to parse the code and assign properties etc. This has downstream effects with generating compiler errors, etc. It's not about the human programmer's ability to reason so any "improved naming" of function names or parameters still won't help the compiler out because it's still just an arbitrary "symbol" in the eyes of the parser.
- jmull 2y agoDownstream effects with generating compiler errors is still about the human programmer's ability to reason about the code, and error messages can only reference the identifier names provided. The compiler doesn't do anything you, the programmer, don't tell it to do. You tell it what to do by writing code using a certain syntax, connecting identifiers, keywords, and symbols. That's it. If the meaning isn't in the identifiers you provide and how you connect them together with keywords and symbols, it isn't in there at all. The compiler doesn't care what identifier names you use, but that's true whether the identifier is for a parameter label, type name, function name or any other kind of name. The programmer gives those meaning to human readers by choosing meaningful names. Anyway, zig's compile errors seem OK to me so far. Actually, the zig comptime programmer can do better than a non-programmable compiler when it comes to error messages. You can detect arbitrary logical errors and provide your own compiler error messages.
- noelwelsh 2y agoI elaborated on parametricity in this comment: https://news.ycombinator.com/item?id=42621239 https://news.ycombinator.com/item?id=42621239 There are many ways one can reason about functions, and I think all of us use multiple methods. Parametricity provides one way to do so. One nice feature is that its supported by the programming language, unlike, say, names.
- jmull 2y agoI saw that. But I don't think it has bearing on zig comptime. zig generates a compile error when you try to pass a non-conforming type to a generic function that places conditions/restrictions on that type (such as by calling a certain predicate on instances of that type). It's probably important to note that parametricity is a property of specific solution spaces, and not really in the ultimate problem domain (writing correct and reliable software for specific contexts), so isn't necessarily meaningful here.
- lmm 2y ago> zig generates a compile error when you try to pass a non-conforming type to a generic function that places conditions/restrictions on that type (such as by calling a certain predicate on instances of that type). Sure, but only after it's fully expanded, which is much harder to debug. And if a generic function doesn't fail to compile but rather silently behaves differently (e.g. if it calls a function that behaves unexpectedly, but still exists, on the type in question) then you don't get an error at all. > parametricity is a property of specific solution spaces, and not really in the ultimate problem domain (writing correct and reliable software for specific contexts) Nonsense. Without parametricity your software is not compositional and it becomes impossible to write correct software to solve complex problems.
- jmull 2y ago> Sure, but only after it's fully expanded, Code goes into the compiler. Either compiled code or errors come out. There's no partial expansion step to cause confusion. You're probably referring to something about the flexibility zig's comptime allows, but it's important to note a zig programmer can be as picky as they want about what types a generic function will accept. People are really just talking about what the syntax for expression type restrictions is. > Without parametricity your software is not compositional and it becomes impossible to write correct software to solve complex problems. You can hold that opinion, but it's not a fact. The overall question isn't binary. It's one of balancing complexity and flexibility. A fixed system for specifying type restrictions is simpler and provides fewer opportunities for mistakes (assuming it's well designed), and may have parametricity. However, the lack of flexibility can just push the complexity elsewhere, e.g., leading to convoluted usage patterns, which could lead to more mistakes. A programmable system for specifying type restrictions offers more flexibility at the cost of more up-front complexity, but in a well-designed system the flexibility could lead to less overall complexity, and fewer mistakes. A nice thing about zig's approach is that the generics metaprogramming language is pretty much the same as the regular language, which mitigates the increase in complexity. I actually think it should be possible to create some kind of generics system that could credibly be said to be programmable and have parametricity, though I don't think there's any point to doing so.