1. 61
  1. 24

    Discussions on other sites: Hacker News, Reddit /r/Zig

    @kristoff, Zig’s VP of Community, replied to this article in those discussions: on Hacker News, the same comment on Reddit

    1. 11

      This is entirely subjective but I have looked at zig a few times and it does feel enormously complicated to the point of being unapproachable. This is coming from someone with a lot of experience using systems programming languages. Other people seem to really enjoy using it, though… to each their own.

      1. 8

        Huh, that’s interesting to hear. Out of curiosity what where the features you found the most complicated?

        I’ve had the exact opposite experience actually. I’m comparing against Rust, since it’s the last systems language I tried learning. Someone described rust as having “fractaling complexity” in its design, which is true in my experience. I’ve had a hard time learning enough of the language to get a whole lot done (even though I actually think rust does the correct thing in every case I’ve seen to support its huge feature set).

        Zig, on the other hand, took me an afternoon to figure out before I was able to start building stuff once I figured out option types and error sets. (@cImport is the killer feature for me. I hate writing FFI bindings.) It’s a much smaller core language than rust, and much safer than C, so I’ve quite enjoyed it. Although, the docs/stdlib are still a bit rough, so I regularly read the source code to figure out how to use certain language features…

        1. 17
          • An absurd proponderance of keywords and syntaxes. threadlocal? orselse? The try operator, a ++ b, error set merging?
          • An overabundance of nonstandard operators that overload common symbols. When I see | and % I don’t think “saturating and wrapping”, even though it makes sense if you think about it a lot. Mentioned earlier, error set merging uses || which really throws me off.
          • sentinel terminated arrays using D, Python, and Go’s slicing syntax is just cruel.
          • why are there so many built-in functions? Why can’t they just be normal function calls?
          • there seem to be a lot of features that are useful for exactly one oddly shaped usecase. I’m thinking of anyopaque, all the alignment stuff… do “non-exhaustive enums” really need to exist over integer constants? Something about zig just suggests it was not designed as a set of orthogonal features that can be composed in predictable ways. That isn’t true for a lot of the language but there are enough weird edges that put me off entirely.
          • Read this section from the documentation on the switch keyword and pretend you have only ever used algol family languages before:
          Item.c => |*item| blk: {
                      item.*.x += 1;
                      break :blk 6;

          It’s sigil soup. You cannot leverage old knowledge at all to read this. It is fundamentally newcomer hostile.

          • what does errdefer add to the language and why does e.g. golang not need it?
          • the async facility is actually quite unique to zig and just adds to the list of things you have to learn

          Any of these things in isolation are quite simple to pick up and learn, but altogether it’s unnecessarily complex.

          Someone said something about common lisp that I think is true about Rust as well: the language manages to be big but the complexity is opt-in. You can write programs perfectly well with a minimal set of concepts. The rest of the features can be discovered at your own pace. That points to good language design.

          1. 13

            I’m thinking of anyopaque, all the alignment stuff…

            Maybe your systems programming doesn’t need that stuff, but an awful lot of mine does.

            what does errdefer add to the language and why does e.g. golang not need it?

            A lot! Deferring only on error return lets you keep your deallocation calls together with allocation calls, while still transferring ownership to the caller on success. Go being garbage-collected kinda removes half of the need, and the other half is just handled awkwardly.

            I didn’t quite see the point for a while when I was starting out with Zig, but I pretty firmly feel errorsets and errdefer are (alongside comptime) some of Zig’s biggest wins for making a C competitor not suck in the same fundamental ways that C does. Happy to elaborate.

            Someone said something about common lisp that I think is true about Rust as well: the language manages to be big but the complexity is opt-in. You can write programs perfectly well with a minimal set of concepts.

            Maybe, if you Box absolutely everything, but I feel that stretches “perfectly well”. I don’t think this is generally true of Rust.

            I think Zig’s a pretty small language once you actually familiarise yourself with the concepts; maybe the assortment of new ones on what looks at first blush to be familiar is a bit arresting. orelse is super good (and it’s not like it comes from nowhere; Erlang had it first). threadlocal isn’t different to C++’s thread_local keyword.

            I get that it might seem more unapproachable than some, but complexity really isn’t what’s here; maybe just a fair bit of unfamiliarity and rough edges still in pre-1.0. It’s enormously simplified my systems programming experience, and continues to develop into what I once hoped Rust was going to be.

            1. 8

              Being unfamiliar, nonstandard and having features for what you consider ‘oddly shaped usecase’ may be exactly what makes it a worthwhile attempt at something ‘different’ that may actually solve some problems of other languages, instead of being just another slight variant that doesn’t address the core problems?

              I personally think it’s unlikely another derivative of existing languages is likely to improve matters much. Something different is exactly what is needed.

              1. 2

                The question is how different we need. Everything must be different or just some aspects?

              2. 3

                what does errdefer add to the language and why does e.g. golang not need it?

                This is a joke, right? Please tell me this is a joke.

                Go does not need errdefer because it (used to?) has if err != nil and all of the problems that came with that.

          2. 12

            I would be more sympathetic if this wasn’t peppered with rather nasty verbiage: “Blech,” “Blech,” “Blech,” “Blech,” “Beyond worthless,” Sarcastic “Cool. Very helpful,” “Horrifically insidious,” use of “Unintuitive” as objective, etc.

            Even if the criticisms are valid, using a polemic tone like this throws shade on the whole set of them because it makes it seem like the author is more interested in confirming an expectation than approaching a new system with an open mind.

            Also, some of the criticisms just don’t make sense to me. The docs are pretty meager, which should make them quick and easy to get through, yet several things ziglearn.org covers appear in this list. The stdlib docs claim they’re not great and refer to the source, the source contains tons of examples of usage in the form of test cases.

            1. 5

              Seems like the exact things this author struggles with are the ones that make Zig good for systems programming.

              1. 28

                Really? The biggest complaints I saw here were “poor/missing/incomplete documentation”, “awkward APIs”, and “poor tooling” (upgrades, package management, etc.)

                I do a lot of systems programming in C++, and I don’t consider any of those to be pluses.

                1. 6

                  awkward APIs

                  I’d guess that depending on how bare-metal you are, you’ll appreciate passing around your allocators, defining print yourself, disallowing non-efficient/static bitshifts and some other annoyances for when you just want to write stuff on a typical x86 machine where you can allow for some overhead and have a defined set of minimum expectations.

                  That said I don’t agree with this either: I think you can allow specifying your own allocators or print functions without sacrificing usability for everything higher level. We’ll see how well the custom allocator addition to rust works out, but my guess is that it’ll work fairly well. And I think core vs std is a nice concept for this duality of “machine” expectations in rust. See also here for an idea of injecting allocators by default without passing them around all the time in rust (which definitely is hidden logic/structure and is a point where I can feel the discussion of complexity).

                  And for me the string matching and printing example rust had back then was definitely a reason to take a look at it. “C(++) with sane string handling ?”

                  poor/missing/incomplete documentation

                  For docs or tooling I won’t judge a pre 1.0 language. Rust just had a huge momentum and @steveklabnik and others just did an awesome job on the docs.

                  1. 4

                    you’ll appreciate passing around your allocators

                    There are times I’ve appreciated setting my allocator, customizing options, etc, but I can’t say I see why I’d appreciate passing it explicitly at each call site that requires one.

                    I’m open to learning that I should appreciate that.

                  2. 3

                    I am a sample size of one but the Zig IRC channel seemed pretty hostile the few times I’ve stuck my head in there. I’ve seen Andrew permaban at least one person for what seemed like a pretty trivial thing.

                    1. 5

                      That doesn’t match my experience in the slightest. First of all, I don’t think I’ve seen more than 3 people banned over the last 2 years I’ve been there and always with good reason. The vibes I get are anything but hostile.

                      I’d suggest spending a longer amount of time before drawing your conclusions.

                      Anyhow, there are public logs of the IRC channel here: https://github.com/marler8997/zig-irc-logs with a WIP frontend: https://marler8997.github.io/zig-irc-webpage/

                      And older pre libera.chat logs with a nicer frontend: https://freenode.irclog.whitequark.org/zig/2021-05-10

                    2. 1

                      “poor/missing/incomplete documentation”

                      From https://news.ycombinator.com/item?id=29966743, as linked by @roryokane:

                      The author also mentioned issues with the autogenerated docs for the standard library. Those docs are currently incomplete and in fact greet you with this message as soon as you open them:

                      These docs are experimental. Progress depends on the self-hosted compiler, consider reading the stdlib source in the meantime.

                      I’ve seen some comments here about how recommending to read the source code is unhelpful. I vehemently disagree because of practicality first (if something is not documented elsewhere, then that’s the best you can do) and second because reading the source code should not be considered something primitive that developers used to do before discovering fire.

                      I think the docs have a ways to go. However, I find myself checking the source regularly even when using C or C++. I think having well-written source code should be step one, while documenting that code well should be step two. So while I think Zig’s docs have a long way to go, I also think they’re on the right track.

                      “awkward APIs”

                      Is this a direct quote? I’m not seeing it anywhere in the article. Perhaps you could remind me where it is brought up.

                      “poor tooling” (upgrades, package management, etc.)

                      Those are all problems. They are also problems that can be solved by adding additional tools (i.e., $ zig <blank>). Thus, I don’t consider them weaknesses in the language. They have much more to do with the limited development power behind the language. That’s not a pass, though; just a reason.

                      Here’s my take:

                      • If you’re looking for a kinda-mature language with promise that already blows C out of the water, Zig is a good choice.
                      • If you’re looking for a fully developed ecosystem with package management up the wazoo, obviously Zig isn’t there yet. Objectively speaking, it’s a matter of scale. In my personal view, it’s only a matter of time.
                  3. 4

                    I also failed to learn Zig via Advent of Code. I used Advent to learn C++, JavaScript, and Rust. I also did 1-3 days in Go and C. I didn’t manage to complete any in Zig. At that time I couldn’t even get the first Hello World in the documentation to compile despite copy/pasting it verbatim. The second Hello World example, when copy/pasted, did compile. To be fair, this was a few years ago (~2019), and I imagine the documentation is better now than it was then.