43,683 karma · joined August 22, 2009
Zig's comptime doesn't do everything that Rust (or Java, or C#, or Swift, etc.) generics do, and I know you know this given your background in type theory. Zig doesn't allow for the inference and type-directed method resolution that Rust or the above languages do, because the "generics" that you create using Zig comptime aren't typechecked until they're instantiated. You can improve the error messages using "comptime if" or whatever Zig calls it (at the cost of a lot of ergonomics), but the compiler still can't reliably typecheck the bodies of generic functions before the compiler does the comptime evaluation.
Now I imagine you think that this feature doesn't matter, or at least doesn't matter enough to be worth the complexity it adds to the compiler. (I disagree, of course, because I find reliable IDE autocomplete and inline error messages to be enormously useful when writing generic Rust functions.) But that's the entire point: Zig comptime is not performing the duty of generics; it's approximating generics in a way that offers a tradeoff.
When I first looked at Zig comptime, it didn't evoke the "magic of Lisp" at all in me (and I do share an appreciation of simplicity in programming languages, though I feel like Scheme offers more of that than Lisp). Rather, my reaction was "oh, this is basically just what D does", having played with D a decent amount in years prior. Nothing I've seen in the intervening years has changed that impression. Zig's metaprogramming features are a spin on metaprogramming facilities that D thoroughly explored over a decade before Zig came on the scene.
Edit: Here's an experiment. Start with D and start removing features: GC, the class system, exceptions, etc. etc. Do you get to something that's more or less Zig modulo syntax? From what I can tell, you do. That's what I mean by "not revolutionary".
For me, those AI tools are much better at saving me time looking up documentation when doing simple things where it has examples of the exact code pattern I'm looking for in its training set. ChatGPT is great at writing one-off Blender scripts for me to give to artists, for instance.
[1]: https://www.seas.upenn.edu/~sweirich/papers/fckinds.pdf
But that's not dependent types. Dependent types are types that depend on values. If all the arguments to a function are either types or values, then you don't have dependent types: you have kind polymorphism, as implemented for example in GHC extensions [1].
> The second half is how every other major feature is expressed _directly_ via comptime/partial evaluation, not even syntax sugar is necessary. Generic, macros, and conditional compilation are the three big ones.
I'd argue that not having syntactic sugar is pretty minor, but reasonable people can differ I suppose.
[1]: https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/poly...
If you say that incomplete implementations count, then I could argue that the C preprocessor subsumes generics/templates, interfaces/typeclasses†, macros, and conditional compilation.
†Exercise for the reader: build a generics system in the C preprocessor that #error's out if the wrong type is passed using the trick in [1].
I think the innovation here is imperative type-level programming--languages that support type-level programming are typically functional languages, or functional languages at the type level. Certainly interesting, but not revolutionary IMO.
That exists; it's called garbage collection.
If you don't want the performance characteristics of garbage collection, something has to give. Either you sacrifice memory safety or you accept a more restrictive paradigm than GC'd languages give you. For some reason, programming language enthusiasts think that if you think really hard, every issue has some solution out there without any drawbacks at all just waiting to be found. But in fact, creating a system that has zero runtime overhead and unlimited aliasing with a mutable heap is as impossible as finding two even numbers whose sum is odd.
It partially is, with codegen units. The problem is that you can't generally do that until codegen time, because of circular dependencies.
[1]: https://www.cpubenchmark.net/cpu.php?cpu=Apple+A18+Pro&id=62...
[2]: https://www.cpubenchmark.net/cpu.php?cpu=Intel+Pentium+4+3.7...
I've measured this, and no, it's not. What you're missing is the complexities of typesetting Unicode and OpenType, where GSUB/GPOS tables, bidi, ruby text, etc. combine to make typesetting quite complex and expensive. HarfBuzz is 290,000 lines of code for a reason. Typesetting Latin-only text in Times New Roman is quick, sure, but that doesn't cut it nowadays.
This is not a knock on Swift--it's really the inevitable outcome of seamless compatibility with the COM-like model of Objective-C and Core Foundation being a guiding principle of the language.
(He's also getting about as close as you can get to the "out-and-out racism" line as you can get without maybe technically crossing it. Though I think he did cross it when it comes to Irish Catholics.)
for (int i = 0; i != n; i++)
sum += a[i];
If n is -2, will this function include the element at a[(uint64_t)INT_MAX + 1] in the sum? If signed overflow is UB, then the answer is "maybe", and thus i and n can legally be promoted to 64-bit. If signed overflow is unspecified, but the result must still fit in a 32-bit integer, then the answer is "no", and i and n can't legally be promoted.I don't know what this means. The optimization becomes invalid if fwrapv is mandated, so compilers can't do it anymore.
"The code was wrong, so it was OK that I made it slower" is a message board argument, not a business argument.
> As for your compiler statement — yes. At least at Apple, there is ongoing clang compiler work, focused on security, that actively makes things slower, and there has been for years.
The performance of code that runs on consumer devices has less of a measurable economic impact than that of code that runs on the server.
There are not. For all the noise that we make on message boards about signed overflow being UB, there are very few actual security problems traceable to it. The problems from it are largely theoretical.
That entire blog post talking about the 0.3% regression illustrates just how much of an effort it is, and how unusual it is, to make those kinds of changes. The reason why Google engineers managed to justify that change is that memory safety results in actual measurable security improvements by enforcing spatial safety. Signed overflow being UB just doesn't make the cut (and let's be clear: at that scale the cost of a 0.3% regression is measured in millions per year).