←back to thread

Zig is hard but worth it

(ratfactor.com)
401 points signa11 | 2 comments | | HN request time: 0s | source
Show context
pron ◴[] No.36150237[source]
> there’s not a direct correlation between the slimness of a language’s syntax and ease of learning

That's absolutely true, but (the standard library aside) the "syntax" -- or, rather the syntax and core semantics -- of a programming language are arbitrary axiomatic rules, while everything else is derivable from those axioms. So while it is true that a small language can lead to a not-necessarily-easy-to-learn overall programming experience, it is the only arbitrary part, and so the only part you need to memorise (or consult the documentation for when dealing with some subtlety you may have forgotten). So a smaller language reduces the need for "language lawyering" after you learn it.

Some languages (e.g. lisps) are deceptively small by relying on macros that form a "second-order" language that interacts with the "first-order" language, but Zig doesn't have that. It has only one language level, which is small and easy to memorise.

But yes, Zig is a bigger language than C, but a far smaller language than C++. What's amazing, though, is that C++ is strictly more expressive than C (i.e. there are programs that could grow exponentially faster in C than in C++, at least without the help of C macros), but Zig is as expressive as C++ (i.e. program sizes may differ by no more than a small constant factor) while being much closer to C in size, and it achieves that without the use of macros.

replies(4): >>36150398 #>>36150954 #>>36151058 #>>36153690 #
the_duke ◴[] No.36150398[source]
I'm not a Zig expert, but I have a different take here.

Zig has comptime, which is essentially a compile time macro written in the main language and with type reflection capabilities.

They can introduce complex behaviour and fail in very cryptic and unexpected ways, which results in an experience very similar to macros or C++ template literals.

replies(1): >>36150717 #
pron ◴[] No.36150717[source]
The objects that are manipulatable by comptime are ordinary program objects and types -- not ASTs. That means that while it's true you can get compile-time errors in similar situations to macros, the errors themselves are like ordinary runtime errors in an untyped language -- while occurring at compile-time, they look like runtime error in Python or JS -- rather than errors due to some "second-order" manipulation of symbols like templates or macros, and so are easier to diagnose (you get a regular stack trace for one).

There is also another interesting difference, albeit a theoretical one. Zig's comptime is what's known in formal languages to be referentially transparent (it basically means that you cannot distinguish between two otherwise identical objects that differ only in their reference name) while macros are not. Because referential transparency is strictly less expressive than "opacity" (but it's also simpler!), it's surprising that so many practical use cases for macros can be addressed with the less powerful (but simpler and much easier to debug) comptime. That's quite a discovery in language design. While other languages also have comptime-like constructs, they also have other complex features that have made it hard to see just how powerful something like comptime alone can be.

replies(3): >>36151303 #>>36151943 #>>36156263 #
1. Symmetry ◴[] No.36151943[source]
I haven't had a chance to play with comptime in Zig yet but I'm sort of curious how it compares to Nim's compile time facilities. You can declare variables with 'var' for true variables, 'let' for things that are runtime constant within a scope, or 'const' for compile time constants whose values can come from functions or whatever as long as it can be resolved by the compiler. And then you've got 'when' as a compile time equivalent of 'if'.
replies(1): >>36152901 #
2. ◴[] No.36152901[source]