19 ms·
Interview with Zig language creator Andrew Kelley [video]
- pron 6y agoI think that Zig's simplicity hides how revolutionary it is, both in design and in potential. It reminded me of my impression of Scheme when I first learned it over twenty years ago. You can learn the language in a day, but it takes a while to realize how exceptionally powerful it is. But it's not just its radical design that's interesting from an academic perspective; I also think that its practical goals align with mine. My primary programming language these days is C++, and Zig is the first low-level language that attempts to address all of the three main problems I see with it: language complexity, compilation speed, and safety. In particular, it has two truly remarkable features that no other well-known low-level language -- C, C++, Ada, and Rust -- have or can ever have: lack of macros and lack of generics (and the associated concepts/typeclasses) [1]. These are very important features because they have a big impact on language complexity. Despite these features, Zig can do virtually everything those languages do with macros [2] and/or generics (including concepts/typeclasses), and with the same level of compile-time type safety and performance: their uses become natural applications of Zig's "superfeature" -- comptime. Other languages -- like Nim, D, C++ and Rust also have a feature similar to Zig's comptime or are gradually getting there -- but what Zig noticed was that this simple feature makes several other complex and/or potentially harmful features redundant. Antoine de Saint-Exupery said that "perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away." I think that Zig, like Scheme -- and yes, there are others -- is close to that minimalist vision of perfection. What a truly inspiring language. Rather than asking how we could make C++'s general philosophy work better as another increasingly famous language does, IMO, it asks how we could reshape low-level programming in a way that's a more radical break with the past. I think it's a better question to ask. Now all there's left to hope for is that Zig gets to 1.0 and gains some traction. I, for one, would love to find a suitable alternative to C++, and I believe Zig is the first language that could achieve that in a way that suits my particular taste. [1]: I guess C has the second feature, but it loses both expressivity and performance because of it. [2]: Without the less desirable things people can do with macros.
- dom96 6y ago> Other languages -- like Nim, D, C++ and Rust also have a feature similar to Zig's comptime or are gradually getting there -- but what Zig noticed was that this simple feature makes several other complex and/or potentially harmful features redundant. I'm curious where this impression of Zig comes from, as this is precisely what Nim has set out to do: a small core extensible via metaprogramming. Are there features that Nim implements which go against this premise? if so, what are they? :)
- deleted 6y ago[deleted]
- pron 6y ago> Are there features that Nim implements which go against this premise? if so, what are they? :) Nim has generics (plus concepts), templates, and macros. Zig has just comptime, through which it achieves all those goals (minus some macro capabilities that it deems harmful anyway) with just one, very simple, cohesive construct. You could argue on whether you like this or not, but you can't argue that Zig's approach isn't fundamentally more minimal. Zig is a language you can reasonably fully learn in one day; I don't think you could say the same about Nim. --- Also, note another remarkable feature. One could define a language called Zig' with the following properties: 1. Every well-formed Zig program is a well-formed Zig' program (i.e. Zig' accepts all Zig programs, potentially more). 2. Every Zig program has the same semantics as the identical program when interpreted in Zig'. This means that to analyse the semantics of a Zig program you can pretend it's a Zig' program; in fact, you don't need to create an interpreter for Zig', you can just pretend it exists. Why would you want to do that? Because Zig' is simpler. How? Here's the kicker: Zig' ignores comptime completely. It is a very simple, optionally-typed, dynamic language with reflection. In other words, to analyse the semantics of a Zig program you can forget about comptime and pretend it can do everything at runtime (and treat comptime as a pure semantics-preserving optimisation). This is not true for languages with macros, as they are not "erasable".
- mratsim 6y ago> Zig has just comptime, through which it achieves all those goals (minus some macro capabilities that it deems harmful anyway) with just one, very simple, cohesive construct. You could argue on whether you like this or not, but you can't argue that Zig's approach isn't fundamentally more minimal. Zig is a language you can reasonably fully learn in one day; I don't think you could say the same about Nim. "some macros" are downplaying Nim macros, it's like saying Lisp has some AST rewrite capabilities. Nim macros goals are two-folds: 1. adding functionality to the language without baking it in the compiler. A prime example is ``async``, ``async`` including a nice async/await syntax can be completely implemented as a library without reserving keywords to do things like `pub async fn`. 2. Automating away boilerplate. From what I understood, Zig comptime is only about making compile-time function evaluation first-class.
- Kednicma 6y agoI hope that we're not stuck writing piles of low-level code for all eternity. We don't need more than a few pages of each low-level language, and while I do really like Zig's qualities compared to C, I'd still like to minimize the amount of Zig or C total that has to be written. I think that our community's equivalent of "where's my flying car?" is "where's my higher-level language?"
- enriquto 6y ago> I think that our community's equivalent of "where's my flying car?" is "where's my higher-level language?" Ηelicopters are flying cars and they are everywhere for you to use. But some people prefer to use a bicycle to commute to work, rather than an helicopter. I'd even say that most people would prefer to take a bicycle every day than an helicopter. The same thing with lower level languages. Sometimes you do not want to be burdened by the limitations of a "high-level" language.
- notacoward 6y ago> Sometimes you do not want to be burdened by the limitations of a "high-level" language. I see very few people suffering from such burdens, but a great many suffering from its exact opposite: using a low- or mid-level language to write hundreds of lines where ten lines in a higher-level language would suffice and be more easily verified as correct.
- ikskuh 6y ago> I see very few people suffering from such burdens, but a great many suffering from its exact opposite: using a low- or mid-level language to write hundreds of lines where ten lines in a higher-level language would suffice and be more easily verified as correct. I see a huge load of people suffering from those burdens. Higher-level languages tend to be less efficient and less optimal. Yes, they take a burden from the programmer and move that burden onto the end user. So the programmer is having the easy life, while every user now waits a second longer for the program startup, a second longer for opening the file dialog, and so on. Doesn't sound much, but if you think about it: Worst case is: 1 programmer shaved off two weeks of work on an app that is used by every person on the planet. 7 billion users lost 1 second. In total, humanity lost roughly 200 years of productive time when every person starts the app exactly once. Modern computers are incredibly fast and we as programmers use that brutal power to be more lazy than before instead of leveraging that power to all of the users of our tools. We could have systems that go from clicking the power button to being readily available for use in less than seconds. Think about this when you chose a high level language that exchanges programmer convenience for runtime cost and think about if it other peoples time is worth your lazyness. </rant> disclaimer: don't take it personally, i'm just frustrated about imperformant software
- deleted 6y ago[deleted]
- rvz 6y agoAt least its C FFI bindings story is much more pleasant than Rust's complicated swiss army knife of toggles and flags in bindgen. The Rustaceans should be taking notes on this.
- kreco 6y agoYeah, that's actually how any C FFI bindings should be. Ans also, that's the strength of C and its simple ABI.
- logicchains 6y agoI work in HFT, and one of the key concerns when writing low-latency code is "is this code allocating memory, and if so, how can I stop it?" Zig is the perfect language for this use case as none of the standard library implicitly allocates, rather for anything that allocates, the caller must pass in an allocator. The stdlib also provides a handy arena allocator, which is often the best choice. This is a huge advantage over C++ and Rust, because it makes it much harder for e.g. the intern to write code that repeatedly creates a vector or dynamically allocated string in a loop. Or to use something like std::unordered_map or std::deque that allocates wantonly.
- AsyncAwait 6y ago> This is a huge advantage over C++ and Rust, because it makes it much harder for e.g. the intern to write code that repeatedly creates a vector or dynamically allocated string in a loop. Or to use something like std::unordered_map or std::deque that allocates wantonly. True. On the other hand, Zig makes a deliberate decision not to bother itself with memory safety too much, so its a win some, loose some sort of situation.
- pron 6y ago> On the other hand, Zig makes a deliberate decision not to bother itself with memory safety too much This is not true. Zig places a strong emphasis on memory safety, it just does so in a way that's very different from either Java's or Rust's. I wrote more about this here: https://news.ycombinator.com/item?id=24293329 https://news.ycombinator.com/item?id=24293329
- littlestymaar 6y ago> It does so with runtime checks that are turned on in development and testing and turned off -- either globally or per code unit -- in production. This isn't “memory safety”, with this reasoning you could say “C is memory safe if you use ASAN during debug”: it is exactly equivalent except Zig checks are less powerful than the full suite of existing sanitizers for C, but it's enabled by default in debug mode, which is nice.
- andi999 6y agoWhat is the best way to start with zig, if you know C by heart? I had a look a while ago, but I feel I miss out how the concepts are to be used in practice.
- kristoff_it 6y agoIf you want to be eased into the language, start by checking out https://ziglearn.org https://ziglearn.org. Otherwise just take a look at the overview on the homepage of https://ziglang.org https://ziglang.org, then the docs. After that you should already be in great shape and you can read the standard library for examples of useful patterns.
- andi999 6y agoIs there something in between homepage and docs? Like 30-50 line workout programs?
- Oreb 6y agoIs the https://ziglearn.org https://ziglearn.org site up to date with the latest versions of the language and standard library? The initial "Hello, World" example fails to compile for me. I get: Semantic Analysis [533/803] ./main.zig:4:14: error: container 'std.debug' has no member called 'print' std.debug.print("Hello, {}!\n", .{"World"});
- pfg_ 6y agoIt's the opposite - you have version 0.6.0, but the hello world there is for the latest master version of zig which can be downloaded at https://ziglang.org/download https://ziglang.org/download
- dnautics 6y agoI was very rusty with c and found learning zig to be a breeze. If you know c by heart you'll do great!
- tobz1000 6y agoSome of Zig's ideas fascinate me, both the great low-level concepts (e.g. arbitrary-sized ints), but much more than that, the high level concepts. Particularly great is Zig's handling of both macros and generic types, the answer to both of which seems to be: just evaluate them at compile-time with regular functions, no special DSL or extra syntax. Andrew mentions in the video a big drawback of this system - implications for IDE complexity and performance. I imagine the performance side of this could be (maybe is?) mitigated by limiting recursion depth/loop counts for compile-time work. I'm not particularly interested in taking on a language with manual memory management and the responsibilities it entails, but I would love to have access to Zig's compile-time capabilities, if it were available with some more memory safety.
- pron 6y agoZig gives you memory safety (or, rather, will ultimately do that), but it does so in a way that's different from both languages with garbage collection (whether tracing or reference-counting) or with sound type-system guarantees a-la Rust. It does so with runtime checks that are turned on in development and testing and turned off -- either globally or per code unit -- in production. You lose soundness, but we don't have sound guarantees for functional correctness, anyway, and given that Zig makes testing very easy, it's unclear whether a particular approach dominates the other in terms of correctness.
- renaicirc 6y ago> You lose soundness, but we don't have sound guarantees for functional correctness, anyway This sounds like "we can't guarantee the most important thing, so it's unclear whether it's useful to guarantee this other thing," but that's a bizarre statement, so am I misinterpreting?
- pron 6y agoIt means that there's a complex tradeoff between making sound guarantees and providing correctness in other ways, a tradeoff that all languages make anyway, each finding its own preferred sweet spot, and that we don't know if, say, Rust's sweet spot yields better correctness than Zig's.
- lokl 6y agoZig is appealing to me, but I wonder whether time spent mastering Zig would be better spent mastering C.
- flohofwoe 6y agoWhy not both? Zig and C are both very simple languages, and there's not much to "master" TBH (at least not many language-specific things, so what you learn mostly transfers to other programming languages as well).
- cmrdporcupine 6y agoTo 'master' C is actually realizing C itself is not as simple as it looks from its syntax. It's an old language and the implementations are by no means straightforward. I'm by no means a C master but I have worked with people who are, and they know nuances of the language and the way it compiles down to various platforms in ways that shame me. But in general I have gone for for generalist not specialist in my career.
- flohofwoe 6y agoWell yes, but in the end all languages have this sort of fractal nature. But there is diminishing value in how deep you want to go into the rabbit hole. Of course there's always more to learn, but with C you're fairly quickly leaving the language and move into the layers of compiler- and hardware-trivia (good to know nonetheless, but often not really relevant for being productive in C) where in other higher-level languages you're still working your way through the standard library ;)
- cmrdporcupine 6y agoC exposes a lot of things, and also hides a lot of things about the underlying system that can get confusing. What's an "int"? Or a "long" You need to know for your platform what the bit width is on your platform, because it's not explicit in the name, and the language is willing to do a bunch of implicit stuff behind the scenes with only a warning or two. Should you really be using 'char'? Is yours a legit use of it or did you mean uint8_t? Other high level languages generally tend to have more sensible default patterns for these things, C ... it gives you all kinds of ammo to shoot yourself with. It's not as big of a problem these days with things becoming less heterogeneous; almost everything is little endian now, much of it 64-bit but at least 32-bit, and we can kind of rely on POSIX being there most of the time. Most new code uses stdint.h and is explicit about word lengths by using int32_t, etc. and follows good conventions there. But venture off the beaten path into odd microcontrollers or into retro machines or port older code or whatever ... and there's glass hidden in the grass all over. C also exposes a model of the machine that looks low level but behind the scenes a modern processor does all sorts of branch prediction and pipelining and so on that can blow up your assumptions. What looks like optimized clever C code can actually end up running really slow on a modern machine, and vice versa.
- kristoff_it 6y agoJust as a reminder, the Zig Software Foundation (501c3 non-profit) is looking for donations in order to be able to pay developers working on the compiler. https://github.com/sponsors/ziglang https://github.com/sponsors/ziglang
- HourglassFR 6y agoI've stumbled upon the Zig language a while back and have been checking in regularly to follow its progress. Recently I took the time to write a very small program to get a feeling for it. My thoughts : - It's a very low level language. Having written mostly Python for the past few years, it is quite the contrast. I had to force myself to think in C to get the train going - Getting my head around the error handling took more time than I'm willing to admit. In the end, it's like having exception but being more explicit about it. It feels nice when you get the hang of it - The documentation of the standard library is severly lacking, to be fair the language is still very young. More worrysome, it feels very cluncky. - No proper string support. It is sad that a modern language still goes down that route after Python has shown that correcting this is both definitely worthwhile and a word of pain. - I have the feeling that optional and error union types are a bit redundant, but I have not written enough Zig to have a real intuition on that. Maybe it is just that I understand monads now.
- gameswithgo 6y agoRegarding strings, nobody doubts that having good string support built into a high level language is a good idea, but with a low level language that has a lot of problems. Especially a language whose design principle is to avoid surprising allocations. So that is necessarily going to make things like concatenating strings more complex, and so on.
- jeltz 6y agoI would hardly use Python as an example of good string support. Of all languages I have worked with it has some of the worst. Look at Rust instead for a modern language with good string support.
- earthboundkid 6y agoI believe OP was saying that the Python 2 → 3 debacle shows it's important to get strings right the first time.
- AnIdiotOnTheNet 6y agoStandard library documentation is indeed clunky as it is auto-generated for the most part. This is something the community has been working on improving but it isn't a priority at this stage in part because the standard library undergoes breaking changes pretty frequently right now. Optional and ErrorUnion are a tiny bit redundant in that one could represent the Optional as another value in an ErrorUnion, and that might even happen as an optimization step in the case of ?!/!? types at some point in the future, but they have very different handling in the language as they are used for very different things. I personally like that Zig doesn't bother with "strings" at a language level at all and just considers everything as arrays of bytes. String handling is a complexity nightmare and I feel that Zig wisely chooses to be simple instead.