This feels like it should've been a git issue rather than a blog post.
No feedback from the author, no explaining what the code does at a level for people new to zig, no explanations of the fundamental problem (i.e. files, buffers, and flow of data, and how to write that as code) and how it relates to what zig is doing, no alternate solution for how zig or other languages might try to solve the problem.
I have a strong suspicion that people are upvoting this based on the title of 'Zig' and 'unsafe' instead of the actual substance of the post.
Decompress's Reader shouldn't depend on the size of the buffer of the writer passed in to its "stream" implementation.
So that's a bug in the Decompress Reader implementation.
The article confuses a bug in a specific Reader implementation with a problem with the Writer interface generally.
(If a reader really wants to impose some chunking limitation for some reason, then it should return an error in the invalid case, not go into an infinite loop.)
So how would the Decompress Reader be implemented correctly? Should it use its own buffer that is guaranteed to be large enough? If so, how would it allocate that buffer?
At the very least, the API of the Readera and Writers lends itself to implementations that have this kind of bug, where they depend on the buffer being a certain size.
> So how would the Decompress Reader be implemented correctly? Should it use its own buffer that is guaranteed to be large enough?
yes
> If so, how would it allocate that buffer?
as it sees fit. or, it can offer mechanisms for the caller to provide pre-allocated buffer(s). in any case the point is that this detail can't be the responsibility of the producer to satisfy, unless that requirement is specified somehow explicitly
in general the new zig io interfaces conflate behavior (read/write) with implementation (buffer size(s))
I ... don't disagree with you. Thanks. It helps my understanding.
I know this is moving the goalpost, but it's still a shame that it [obviously] has to be a runtime error. Practically speaking, I still think it leaves lot of friction and edge cases. But what you say makes sense: it doesn't have to be unsafe.
Makes me curious why they asserted instead of erroring in the first place (and I don't think that's exclusive to the zstd implementation right now).
Like a modern C with lessons learned. Instead of macros it uses Zig itself to execute code at runtime (comptime). Custom allocators are the norm. No hidden control flow, everything is very explicit and easy to follow.
But it’s not only the language itself, it is also the tooling around it. Single unit of compilation has some nice properties, allowing to support colorless async. Fast compile times. Being able to use existing C code easily and having optimization across language boundaries. Cross compilation out of the box. Generally caring for performance in all aspects.
So for me it is a better C, low-level but still approachable and not having so much cruft.
> Instead of macros it uses Zig itself to execute code at runtime (comptime).
Nice. FWIW, I have a vague PL design in my head that does this despite being a much higher-level language. (For that matter, I think of my idea much as "like a modern Python with lessons learned".) Point being I definitely think this is a good idea.
To my understanding, the things actually called "macros" in Lisp also do this.
> Custom allocators are the norm.
On the other hand, this doesn't sound to me like an upside. Of course it's fine and well if it's easy to do this. But hopefully you'd prefer not to have to... ?
> No hidden control flow, everything is very explicit and easy to follow.
What sort of hidden control flow do you see in C? (Are modern code bases using setjmp/longjmp in new code?) I would have thought that C++ is where that really started, via exceptions. But I also don't think most programmers see that as problematic for understanding the code.
> Single unit of compilation has some nice properties, allowing to support colorless async.
Would appreciate some explanation of the theory here. Though it does occur to me that the languages I can easily think of with "coloured" async also don't exactly statically link everything all the time.
Also, how does all of this compare to Rust, in your view?
Comptime is very nice but certainly more limited then Lisp. You can't generate arbitrary code with it. But good enough to implement something like JSON serialization or Struct-of-Arrays in normal code that is readable.
Custom allocators are very nice. We are very much in manual memory management + optimization territory here. Having things like arena allocators makes a lot of difference in specific use-cases when you want/need every bit of performance. Also nice being able to switch the allocator for tests that is able to report leaks for example.
Yes, hidden control flow I mean something like exceptions, RAII or Rust's Dispose. So more a comparison to other languages than C.
The explanation I would refer to the talks "Don't forget to flush" or "Zig Roadmap 2026" from Andrew Kelley. Also the blog post "Zig's New Async I/O". I think it has something to do with being able to infer the required size of the stack, but already forgot the details.
As to compared to Rust. The fast compile times are nice. Having a small language that you actually can understand helps to be productive. Not being restricted by the borrow checker makes it easier to implement some low-level things. Just being able to import most C code without wrapper makes the smaller ecosystem a much smaller problem. Rust is nice and certainly a good pick for many cases, but personally I often feel overwhelmed by the complexity and tons of tons of types for everything.
It's clear once you know that an object implements the Drop trait, but you can't see that at the use site, ergo it's hidden (same goes for C++ destructors). Zig wants every call to be visible.
The tradeoff is between making sure you don't forget to write the cleanup call (Rust, C++) and making sure you don't forget to read the cleanup call (Zig). For low-level code I personally prefer Zig's tradeoff; others prefer the C++/Rust tradeoff.
A funny thing I’ve noticed is that some Rust programmers will explicitly call `std::mem::drop(…)` in tricky situations where it really matters, like releasing a mutex with complex interactions - even at the end of scope. I kind of like it whenever a lock is held for more than a few lines.
I think it’s a good compromise, because the consequences of forgetting it are way harsher. Memory leaks, deadlocks…
> On the other hand, this doesn't sound to me like an upside. Of course it's fine and well if it's easy to do this. But hopefully you'd prefer not to have to... ?
Why wouldn't you? You can often make your code simpler and more performant by using certain allocation strategy rather than relying on global allocator. Malloc/Free style strategy is also very error prone with complex hierarchical data structures where for example arena allocation can tie the whole lifetime to a single deallocation.
> Would appreciate some explanation of the theory here. Though it does occur to me that the languages I can easily think of with "coloured" async also don't exactly statically link everything all the ti
Async is moot point, it does not exist in zig right now, it used to but it was removed. There are plans to reintroduce it back, but using async as any sort of benefit for zig is not being honest.
It has proper arrays and slices, even being able to define a sentinel value in the type system, so you know when it is a C string or a slice with a specific size with arbitrary values. Strings can become a problem if you need another encoding than the chosen one. Then you start to use byte slices anyway. You need to allocate a new one if you want to change just a part of it. Safer yes, but can produce unwanted overhead and you have to duplicate many APIs for strings and byte arrays as it is the case in Go.
AST macros are very powerful. As to them being "good", that's debatable. They have advantages but also disadvantages. For one, they operate on syntax, so they're a separate metalanguage and not so pleasant to debug. For another, they are referentially opaque (i.e. when passed different expressions with the same meaning, they can produce different results), which makes them powerful but also mysterious.
What's interesting about Zig's comptime is that while it's strictly less powerful than AST macros, it can do a lot of what macros can do while not being a metalanguage - just Zig.
Not only being text based but also having another separate language is problematic. Rust also has powerful declarative macros but it is it’s own language. Procedural macros and crabtime are imho a bit better for more complex cases as you write Rust.
I've seen the custom allocators mentioned many times as central to the value proposition. Do the allocators shipped with the standard library compose the system allocator, or are they completely distinct from the *alloc family shipped as part of libc?
You can ofc use the *alloc from libc if you want. Otherwise there are different ones in the standard library, ArenaAllocator wraps another allocator, FixedBufferAllocator uses a given byte slice. I recommend to take a look at https://ziglang.org/documentation/master/std/#std.heap to get an overview.
Zig’s undefined behavior story is not nearly as much of a minefield for one. That should be enough really. If you think the CPP is good enough for metaprogramming, I don’t know what to tell you either.
It's a language that attempts to solve more of the biggest issues with low level programming than any other current low-level programming language. Of course, there is nowhere near a universal consensus on what the biggest issues are, but here's what they are to me in order of importance (and I'm not alone):
1. Language complexity/lack of expressivity. You want code, as much as possible, to clearly express the algorithm at the level of detail needed at the language's domain, no more and no less. The level of detail in low-level languages is different from high-level languages because, for example, you want to see exactly where and when memory is allocated/freed. Both C and C++ fail at this for opposite reasons. C is often not expressive enough to express an algorithm clearly (at least not without the use of macros), and C++ is often too implicit, hiding important details that are then easy to miss [1]. These problems may affect program correctness.
2. Lack of spatial memory safety, which is the cause of the #2 and #6 most dangerous software weaknesses (https://cwe.mitre.org/top25/archive/2024/2024_cwe_top25.html). Unlike spatial memory safety, Zig doesn't guarantee the lack of temporal memory safety. This would have been very nice to have, but it isn't as important and not worth compromising on the other top points.
3. Slow build times, which may also affect correctness by slowing down the test cycle.
I don't find Zig similar to C or C++ at all (certainly not as similar as Rust is to C++). If anything, Zig's risk is in being a more revolutionary step than an evolutionary one.
---
[1]: In the late eighties/early nineties (when I first learned C++), when we thought it might be a good idea for a language to be both low-level and high-level, C++'s notion of "zero-cost abstractions" seemed very interesting and even promising (I don't recall them being given that name then, but the problem - or advantage - was right there at the beginning; e.g. whether a call uses static or dynamic dispatch is an algorithmic detail that may be of interest in low-level programming, as well as whether a destructor is called, possibly through dynamic dispatch). Now that notion feels an outdated vestige of a bygone era. I'm aware there are still C++ programmers who still believe in writing high level applications in low-level languages and still believe in zero cost abstractions, but I think the industry has clearly been going the other way, and there's no indication it may be changing direction or may have any reason to do so.
I believe that in modern times, this term refers to stuff like: transparent conversion to a low-level representation (e.g. a bit-packed integer) from a high-level, statically checked datatype - e.g. a tagged union with exhaustive pattern matching, aka ADT. This is also something C++ etc lack.
The value proposition of Zig is it's the most ergonomic way to do systems programming I've ever seen. First class allocators, arbitrary width integer types, top notch bindings to OS syscalls in the std lib without relying on libc, and you can translate C bindings to Zig at compile time, so no FFI layers for existing libraries.
They sometimes write about how they're a general purpose language, but I strongly disagree. It's unapologetically a systems programming language; that's it's entire focus.
It's a powerful alternative to Rust and C++ for writing ultra low latency code when safety isn't important, like games or HFT. Its standard library and ecosystem have excellent support for passing around allocators and no hidden dynamic allocation (every function that allocates takes an allocator as a parameter), which makes it much harder to hit the latency pitfalls common to Rust and C++. It also encourages the latency-optimal approach of using local bump-a-pointer arena allocators where possible rather than the slow global allocator. And finally, the superior metaprogramming support makes it more convenient to use high performance techniques like struct-of-arrays.
Rusty rust and C++-y C++ are both often slower than hand-rolled C for a given function, and zig is intended to be a better way to hand-roll some C.
C as a language is obsessed with the fact that C runs everywhere. Even on a DSP with a 24-bit char and a 24-bit int. If you take out those complexities and you add 40 years of lessons on language design, you can make something a lot simpler.
I don't think there is such a specific thing and certainly disagree that all idiomatic rust is somehow slower by default.
You can write rust like you might write a higher level language and then that can end up slower but if you write idiomatic low level rust, the performance is much harder to compare with C. There are things which will be faster in C and things which will be faster in Rust but broadly things will be extremely similar in performance.
I write bare metal embedded rust a lot these days and there are quite complex concepts you can represent in rust which make your code a lot safer without a performance hit.
Idiomatic "low level" rust clocks in at about 10-50% slower than hand-coded C every time I try it. It is also about 10x easier to write the Rust code. Unsafe is just required a lot of the time. Sometimes it's code size or struct size just being larger to express a similar concept. To get back your performance you have to do things that are un-idiomatic (but you have to do in C anyway).
1. Rust structs are generally smaller due to layout optimization.
2. A 10-50% difference is well within the “are you measuring debug builds?” territory.
I’m curious what code you are writing that requires unsafe all the time? I do a lot of low-level optimization, and unsafe is barely ever actually needed.
It sounds like you work with people who don't really know C. Understanding how to pack a struct is a pretty basic skill. Write an optimized database or network stack without unsafe for me.
I’m not really sure what your point is by linking the benchmarks game. I mean, it’s a fun activity, but this is saying nothing about C vs. Rust. It may or may not be saying something about GCC vs. LLVM.
“Safety” as defined in the context of the Rust language - the absence of Undefined Behavior - is important 100% of the time. Without it, you are not writing programs in the language you think you are using.
That’s a convoluted way to say that UB is much, much worse than you think. A C program with UB is not a C program, but something else.
Your comment was corrected or written by ChatGPT, right? It's super interesting that I can recognize these things now. The specific usage of punctuation, certain words and sentence construction.
Crashes from safety bugs are rare in HFT because they can replay years of data against code changes. For a strategy that trades in and out of positions quickly and is flat most of the time, it's also often not a big deal if the program crashes in the midst of running, as long as some technique has been arranged to cancel resting orders and alert a trader (who is generally monitoring the system's operations at all times).
They're certainly not inclined to pursue safety at any expense of performance in their code.
>Safety not important in HFT? You'd better make sure those precious microseconds buy you enough to make up for when things go awry.
Memory safety bugs are very rare in modern, well-written and tested C++. The key difference is that there are no adversarial inputs, while something like a browser or server needs to deal with potentially adversarial inputs, making absolute memory safety much more important (as even a single memory safety issue could be exploited).
Being the anti Rust alternative for people who has spent years/decades accumulating weird knowledge about the inner workings of C and/or C++ and maintain that being able to shoot your feet off at a distance when doing the wrong incantation is a critical feature to have.
I’m ranting but based the Rust/Zig discussions here on HN and the number of segfault issues in the Bun repo there is a core of truth.
Or Rust being the anti Zig alternative for people who have spent years/decades accumulating weird knowledge about the finer details of type systems and maintain that not being able to express an algorithm, or review one, without consulting a language lawyer (or becoming one) is a critical feature to have and that build times don't matter.
The point is that all languages, including those two, make very clear and sometimes significant tradeoffs that may be more or less appropriate in different circumstances or for different people, and, at least so far, no consensus about the "right" tradeoff has emerged.
It was a joke premised on the implicit assumption that Zig must be an "anti-Rust" because it came later. Maybe you could call different approaches contrarian if Rust had achieved some great popularity or consensus, but it hasn't. Rust's adoption rate is low because many don't find it enticing enough, and so it's unsurprising that there are several other approaches in the space of low-level programming - which is due for some update - that are all different from each other. Their attempts to improve on C and C++ in different ways don't make them "anti" anything else.
Oh, I'm very pro Rust. I think that its use of the borrow checker is inspired and quite spectacular, that we can learn a lot from it. I just don't like it (as a practical programming language). It's not for me and for people who have similar preferences.
I am, however, very much anti claims made by some Rust fans that take an empirical and universal nature and are simply not known to be true (e.g. it is true that the more memory safety guarantees the fewer the vulnerabilities - all else being equal - but it is quite simply logically incorrect to conclude from that that the best way to minimise vulnerabilities is to have more sound safety guarantees).
I think Rust is a fantastic fit for some people who want to do low-level programming, and a pretty bad fit for others (like me). Same goes for Zig or, really, almost any language. Obviously, neither one is inherently or universally superior to the other.
BTW, my enthusiasm for Zig is not because I like all of its design decisions, but mostly because it's so different from most other languages and, in some cases, its decisions run contrary to my personal inclination (e.g. with regards to encapsulation) that I'm fascinated to know how it works out. Rust, on the other hand, is less interesting for me to think about, because aside from the more intensive typechecking (that I'm already familiar with from other languages) the overall experience it offers is quite similar to C++. Maybe I won't like what Zig ends up becoming, but for someone who's seen so many languages, it's really interesting to come across something so fresh.
There is plenty of room for both languages to exist. Engineering is all about trade offs.
Rust has some big pluses but it's not suitable for every application.
People keep thinking that even though Microsoft, Apple, Google, etc. with all the incentive and tooling in the world couldn't evade one of the few replicable results in programming languages (people can't reliably write memory safe code in memory unsafe languages), somehow with Zig it will be different. It's honestly a pretty fascinating phenomenon to me because most of these people are smart, and some of them are even ostensibly in the security community.
We have language groupies now, like how teenagers have their favourite k-pop bands, I wouldn't take it all so seriously. Security has a tendency of making itself undeniable, it's lessons will be learned one way or another by everybody without exception.
Zig's pointless choice to avoid global constructors - something all platforms have supported for several decades by now - makes I/O extremely unwieldy. That alone prevents it from being a viable mainstream language.
There is a lot of useful technical work and ideas in it though.
What a terrible way to take constructive feedback.
Writing not one but two blog posts takes time and effort, moreso when it includes investigation and examples... the posts are not just low effort "this is crap" rants (and they even blame themselves, even though it's clear from the posts that there are documentation/discoverability issues).
What if the poster doesn't feel knowledgeable enough to contribute code? (as shown by his first post title, "I'm too dumb for...")
If that's not collaborating I don't know what it is...
That's not the read I got from Andrew's comment, or the situation. If the poster doesn't feel knowledgeable/able enough to collaborate in the community discussions (like the issue links, which don't require contributing code) then doing individual blog posts instead is only going to give even worse results for everyone.
Blog posts are collaboration (1). I did get the sense that Andrew doesn't see it that way. (And for this post in particular, and writegate in general, I have been discussing it on the discord channel. I know that isn't an official channel).
My reasons for not engaging more directly doesn't have anything to do with my confidence / knowledge. They are personal. The linked issues, which I was aware of, are only tangentially related. And even if they specifically addressed my concerns, I don't see how writing about it is anything but useful.
But I also got the sense that more direct collaboration is welcome and could be appreciated.
(1) - I'm the author of The Little MongoDB Book, The Little Redis Book, The Little Go Book, etc... I've always felt that the appeal of my writing is that I'm an average programmer. I run into the same problems, and struggle to understand the same things that many programmers do. When I write, I'm able to write from that perspective.
No matter how inclusive a community you have, there'll always be some opinions and perspectives which get drowned out. It can be intimidating to say "I don't understand", or "it's too complicated" or, god forbid, "I think this is a bad design"; especially when the experts are saying the opposite. I'm old enough that I see looking the fool as both a learning and mentoring experience. If saying "io.Reader is too complicated" saves someone else the embarrassment of saying it, or the shame of feeling it, or gives them a reference to express their own thoughts, I'm a happy blogger.
I don't even like Zig but I read your blog for the low level technical aspects. I agree completely that blog posts are collaborative. I read all kinds of blogs that talk about how computers work. I can't say if it brings value to the Zig people, but it certainly brings value to me regardless!
Author is posting honest and respectful critique of Zig features on their blog. That is a valid way of collaborating in the community discussion. The project github isn't the only place where discussion is allowed to take place.
The claim isn't you should shut down your blog and only talk on GitHub to be engaged with the community. Zig has tons of communities https://github.com/ziglang/zig/wiki/Community and, of course, blogs also play a part in the overall community too. Picking a single engagement option is probably always a poor choice, but that option being your personal blog alone would be one of the poorest. That's where the feeling of lack of collaborating with the community is coming from, not that they specifically don't engage in GitHub alone.
Make blog posts, it's great!, but if you don't think you're the expert then they'll go a lot farther for everyone if you put 5% of the work of doing so into engaging with the community about it for additional insights first. That's a fair note to make, though I agree the ending could be less passive aggressive about those who don't want to engage with the community.
FWIW as someone with only a pinky toe in the Zig community, it's quite engaging and interesting to see a blog post like this. It makes me want to learn more, and reminds me that there's a wide tent here (that might even include me!), not just a tight-knit "inside" group.
> Kinda wish the author would attempt to collaborate rather than write stuff like this [...] but, whatever, it’s their blog so they can do what they want.
...feels like passive aggression. In particular the "stuff like this" (like what?) and "but, whatever" felt very unnecessary and the whole "I wish he'd collaborate on my terms" is IMO uncalled for.
Yeah, I could see it being better without that portion of the final sentence. At the same time, I think opening "What a terrible way to take constructive feedback" is at least equally as grating a way to engage about it - but at the end of the day we're all humans, not saints, and it seems clear to me both comments are well intentioned and decently put as a whole. Same as me, I'm sure if I look back at these comments in 3 days there will be parts I would have changed, but overall I'd probably thing they were decent instead of terrible.
I'm glad you made the note about that part though, I agree with it and we can always do better.
I think it's likely that both the blog poster and the maintainer are being perceived as more negative in tone than the intent / reality. They both included disclaimers "I must be doing something wrong. And if I am, I'm sorry." and "whatever, it’s their blog so they can do what they want." They're also both giving critical feedback "But, if I'm not, this is a problem right?" "Kinda wish the author would attempt to collaborate rather than write stuff like this" but in both cases the criticism is extremely mildly worded compared to most toxic online discourse. This seems... great? Isn't it good we're able to disagree so politely? It's not toxic to have a disagreement or to give critical feedback. We don't need to all pretend to agree with each other all the time or be happy with each other in order to have a civil discourse.
It depends on context. When someone raises a potential objection and then says "but whatever" they are being dismissive towards their own objection. This is also called "letting it go" or "moving on".
And posting direct links to the places where discussion actually happens along with providing tldr context is as constructive as you can get.
But whatever :)
Collaborating would be contacting the Zig team through one of the many channels available and asking questions, offering suggestions etc. Posting critical blog posts without doing this first is counter-productive, and can even be seen as self promotion. After all, we're now discussing the blog posts, and not the actual issues. Would this have happened if the author had just sent an email to the mailing list or asked on Github?
Nah, this is absurd. This guy or anybody else can write whatever they want, whenever they want, on their own blog. They are under zero obligation to create bug reports, file issues, check in on a chat channel, or contribute in any other way to an open source software project that does not employ them. Writing blog posts is a perfectly reasonable and normal community behavior.
The members of the Zig project are free to reach out to the author!
When you create a project in public people will write about it, tweet about it, complain about it, etc (if you’re lucky!).
Intermernet said, "Posting critical blog posts [...] is counter-productive."
You said, "anybody [...] can write whatever they want". "They are under zero obligation ...". "Members of the Zig project are free to reach out ..."
Do you not realize that you have not at all addressed the point about what is the most productive way to criticize?
All you have done is go off about people's rights, freedoms, and lack of obligations. But nobody actually said "People shouldn't be able to post critical blog posts" or "People are obligated to participate by filing issues or contributing code to open source". So what was the point in saying this? Do you think people believe anything contrary to what you said?
The parent quite literally made a normative statement and I disagreed with it:
> Collaborating would be contacting the Zig team through one of the many channels available and asking questions, offering suggestions etc.
If nothing else, this is attempting to define what counts as valid collaboration, and it's a definition I reject, so I disagreed with it. Good-faith experience reports are valid, useful, pro-social collaboration. Doing so is a perfectly productive way to criticize.
> So what was the point in saying this? Do you think people believe anything contrary to what you said?
Apparently they do. The parent even made a veiled accusation that the author writing a good-faith blog post on their own blog about their own experiences "can even be seen as self promotion". Since when is sharing your good-faith critique about the design of a tool you've used something underhanded or nefarious?
Setting the bounds of valid community collaboration to "people can post on their own blog as long as I like it otherwise they're being mean" is not a set of values I subscribe to, so I felt it was worth it to articulate that.
Why is this counter-productive and self promotion? Does that mean we should all stop writing programming related blog posts? And move all the discussions into GitHub issues only?
Andrew wrote ONE SENTENCE and that's enough for you to diagnose him? That's enough for you to identify a pattern of behavior? Really?
He's "polishing a pig"? He's hiding "all issues" with Zig in internal mailing lists to "project a polished facade"? ALL?! You got all that from one sentence saying he wishes the author took a different approach?
Alright, fine. Here's my analysis of your character and lifelong patterns of behavior based on your first two sentences:
You just want to tear down everybody who is trying to do good work if they make any mistake at all. You look for any imperfection in others because criticizing people is the only approximation of joy in your existence. You are the guy that leaves Google reviews of local restaurants where you just critique the attractiveness of the women who work there. You see yourself as totally justified and blameless for your anti-social behavior no matter the circumstances, and you actually relish the idea of someone being hurt by you because that's all the impact you could hope for.
If that's not accurate to who you are, well, ¯\_(ツ)_/¯ that's just how it reads to me.
> Kinda wish the author would attempt to collaborate rather than write stuff like this and I’m too dumb for Zig’s new IO interface but, whatever, it’s their blog so they can do what they want.
Damn, Andrew Kelley really come across as a dickhead when taking any bit of criticism about his language, often painting them as bad actors trying to sabotage the language.
This isn't the first time he repeats this behavior.
That all seemed pretty adult and tame. Maybe slightly stand-offish at worst. And I tended to agree with Andrew in that thread. A project like Zig is an absolutely massive undertaking. I can cut Andrew some slack. Not everyone is perfect all the time, and his behavior there was nowhere close to BS I have seen in other open source projects. Ahem, Linus.
Did you read until the end of the thread? I was thinking the same at first but only because it took awhile for the conversation to play out.
From my plain reading he didn't take time to understand the proposal before providing feedback. That's fine as far as being busy or miscommunication goes, it happens, but after it was pointed out he never apologized or offered more constructive feedback. Which again is fine, but I'd expect a technical leader to not isolate the maintainers of their most critical dependency. Clearly he gave them a terrible first impression.
I'm not even sure that it's criticism. I read it as a genuine open question.
At least in my experience, asking questions like this through GitHub issues or a mailing list are met with negativity. I don't want to post through a channel where I'll get a snide, terse response from a maintainer. I'd much rather post to my blog audience, who I find to be generally knowledgeable and friendly enough to already be following me. And if I found an answer, I'd post about it and explain what I learned in the process, linking from the existing post.
In a lot of ways, I think Andrew's response is exactly the sort of flavor of reply that I would have expected no matter what channel the question had been posed through, and that's exactly why I wouldn't have gone through those channels if I was the author. His reply didn't answer the question aside from implying it's maybe an issue, nor did it invite feedback.
Quite. I don't think it's unreasonable to expect someone to check the issue tracker before blogging and I don't think Andrew's response was at all problematic.
I'd say the only issue what the "too dumb, but whatever" comment.
That should have been removed and it would have been totally reasonable.
Edit: Oh actually, the author has another blog post titled "I'm too dumb for Zig ...". With that context, it makes sense and I agree it's a reasonable response. I'm sure other readers like me didn't know that context though.
In any case I've seen how communities treat the authors of important projects that touch their livelihood or habits to be unsurprised an author may lose it at times.
Andrew may be expressing frustration or dismay or annoyance in that statement, but he is not definitively "painting them as bad actors trying to sabotage the language". You are HEAVILY reading into his statement.
He only said he wishes the author would have taken a different approach. So what? Why does everyone have to jump in and start psychologizing or essentializing Andrew based on one paragraph?
Why does one paragraph have to say so much about who he is as a person? Even if it did piss him off for a few hours, so what? He's not allowed to wish someone took a different approach?
I tend to think Andrew Kelley is a great guy, not just technically but as a person. And I think that because I've listened to him talk for dozens of hours. I can guarantee you that that one sentence he wrote is not the beginning of a character assassination campaign against the author of this blog.
He made Zig because he wanted to put something good into the world and improve the state of software. How about we include that in our analysis of Andrew's character? I'll leave it to the reader to consider whether the multi-year full time dedication to Zig should be weighed more heavily than a personal feeling he had for two minutes that he expressed respectfully without attacking anyone's character.
From his "Open Letter to Everyone I've Butted Heads With":
> My friend - it's not personal. I care about you. I actually do value your opinion. I'm interested in your thoughts and feelings. I want to make you happy. I'm sad that I can't serve you better with my open source project. I want to. I wish I could.
> I'm hustling. I'm playing the game. I'm doing what it takes to make this thing mainstream and a viable, practical choice for individuals and companies. If you talk shit about Zig in public, I'm going to fight back. But I respect you. I see you. I understand you. I don't hate you. I would literally buy you a drink.
I know what you mean, but name-calling has got to be one of the worst ways to call for some decorum. It just leads to flame wars. (Be the change you want to see, and all that.)
This feels like it should've been a git issue rather than a blog post.
No feedback from the author, no explaining what the code does at a level for people new to zig, no explanations of the fundamental problem (i.e. files, buffers, and flow of data, and how to write that as code) and how it relates to what zig is doing, no alternate solution for how zig or other languages might try to solve the problem.
I have a strong suspicion that people are upvoting this based on the title of 'Zig' and 'unsafe' instead of the actual substance of the post.
I think there's just a bug somewhere, not a general "safety" problem.
Then in the top-most snippet, what size should `buffer` be?
It shouldn't matter.
Decompress's Reader shouldn't depend on the size of the buffer of the writer passed in to its "stream" implementation.
So that's a bug in the Decompress Reader implementation.
The article confuses a bug in a specific Reader implementation with a problem with the Writer interface generally.
(If a reader really wants to impose some chunking limitation for some reason, then it should return an error in the invalid case, not go into an infinite loop.)
So how would the Decompress Reader be implemented correctly? Should it use its own buffer that is guaranteed to be large enough? If so, how would it allocate that buffer?
At the very least, the API of the Readera and Writers lends itself to implementations that have this kind of bug, where they depend on the buffer being a certain size.
> So how would the Decompress Reader be implemented correctly? Should it use its own buffer that is guaranteed to be large enough?
yes
> If so, how would it allocate that buffer?
as it sees fit. or, it can offer mechanisms for the caller to provide pre-allocated buffer(s). in any case the point is that this detail can't be the responsibility of the producer to satisfy, unless that requirement is specified somehow explicitly
in general the new zig io interfaces conflate behavior (read/write) with implementation (buffer size(s))
I ... don't disagree with you. Thanks. It helps my understanding.
I know this is moving the goalpost, but it's still a shame that it [obviously] has to be a runtime error. Practically speaking, I still think it leaves lot of friction and edge cases. But what you say makes sense: it doesn't have to be unsafe.
Makes me curious why they asserted instead of erroring in the first place (and I don't think that's exclusive to the zstd implementation right now).
This seems like it's maybe unwise but I can't see how it's unsafe ?
I've seen Zig popup a lot recently.
What's the value proposition of Zig? It's not immediately obvious to me.
Is it kind of like the Kotlin of C, going for a better syntax/modern features but otherwise being very similar?
Like a modern C with lessons learned. Instead of macros it uses Zig itself to execute code at runtime (comptime). Custom allocators are the norm. No hidden control flow, everything is very explicit and easy to follow.
But it’s not only the language itself, it is also the tooling around it. Single unit of compilation has some nice properties, allowing to support colorless async. Fast compile times. Being able to use existing C code easily and having optimization across language boundaries. Cross compilation out of the box. Generally caring for performance in all aspects.
So for me it is a better C, low-level but still approachable and not having so much cruft.
> Instead of macros it uses Zig itself to execute code at runtime (comptime).
Nice. FWIW, I have a vague PL design in my head that does this despite being a much higher-level language. (For that matter, I think of my idea much as "like a modern Python with lessons learned".) Point being I definitely think this is a good idea.
To my understanding, the things actually called "macros" in Lisp also do this.
> Custom allocators are the norm.
On the other hand, this doesn't sound to me like an upside. Of course it's fine and well if it's easy to do this. But hopefully you'd prefer not to have to... ?
> No hidden control flow, everything is very explicit and easy to follow.
What sort of hidden control flow do you see in C? (Are modern code bases using setjmp/longjmp in new code?) I would have thought that C++ is where that really started, via exceptions. But I also don't think most programmers see that as problematic for understanding the code.
> Single unit of compilation has some nice properties, allowing to support colorless async.
Would appreciate some explanation of the theory here. Though it does occur to me that the languages I can easily think of with "coloured" async also don't exactly statically link everything all the time.
Also, how does all of this compare to Rust, in your view?
Comptime is very nice but certainly more limited then Lisp. You can't generate arbitrary code with it. But good enough to implement something like JSON serialization or Struct-of-Arrays in normal code that is readable.
Custom allocators are very nice. We are very much in manual memory management + optimization territory here. Having things like arena allocators makes a lot of difference in specific use-cases when you want/need every bit of performance. Also nice being able to switch the allocator for tests that is able to report leaks for example.
Yes, hidden control flow I mean something like exceptions, RAII or Rust's Dispose. So more a comparison to other languages than C.
The explanation I would refer to the talks "Don't forget to flush" or "Zig Roadmap 2026" from Andrew Kelley. Also the blog post "Zig's New Async I/O". I think it has something to do with being able to infer the required size of the stack, but already forgot the details.
https://kristoff.it/blog/zig-new-async-io/ https://youtu.be/f30PceqQWko?si=g2nLTE4ubWD14Zvn https://youtu.be/x3hOiOcbgeA?si=SUntYOYNOaxCRagc&t=3653
As to compared to Rust. The fast compile times are nice. Having a small language that you actually can understand helps to be productive. Not being restricted by the borrow checker makes it easier to implement some low-level things. Just being able to import most C code without wrapper makes the smaller ecosystem a much smaller problem. Rust is nice and certainly a good pick for many cases, but personally I often feel overwhelmed by the complexity and tons of tons of types for everything.
Rust dispose? I think you mean drop. But I don't see how that is hidden control flow. It's very clear when it drop is called.
It's clear once you know that an object implements the Drop trait, but you can't see that at the use site, ergo it's hidden (same goes for C++ destructors). Zig wants every call to be visible.
The tradeoff is between making sure you don't forget to write the cleanup call (Rust, C++) and making sure you don't forget to read the cleanup call (Zig). For low-level code I personally prefer Zig's tradeoff; others prefer the C++/Rust tradeoff.
A funny thing I’ve noticed is that some Rust programmers will explicitly call `std::mem::drop(…)` in tricky situations where it really matters, like releasing a mutex with complex interactions - even at the end of scope. I kind of like it whenever a lock is held for more than a few lines.
I think it’s a good compromise, because the consequences of forgetting it are way harsher. Memory leaks, deadlocks…
> On the other hand, this doesn't sound to me like an upside. Of course it's fine and well if it's easy to do this. But hopefully you'd prefer not to have to... ?
Why wouldn't you? You can often make your code simpler and more performant by using certain allocation strategy rather than relying on global allocator. Malloc/Free style strategy is also very error prone with complex hierarchical data structures where for example arena allocation can tie the whole lifetime to a single deallocation.
> Would appreciate some explanation of the theory here. Though it does occur to me that the languages I can easily think of with "coloured" async also don't exactly statically link everything all the ti
Async is moot point, it does not exist in zig right now, it used to but it was removed. There are plans to reintroduce it back, but using async as any sort of benefit for zig is not being honest.
> Like a modern C with lessons learned.
Yet no string types. So lessons not so well learned. Zig does remove many warts in C.
It has proper arrays and slices, even being able to define a sentinel value in the type system, so you know when it is a C string or a slice with a specific size with arbitrary values. Strings can become a problem if you need another encoding than the chosen one. Then you start to use byte slices anyway. You need to allocate a new one if you want to change just a part of it. Safer yes, but can produce unwanted overhead and you have to duplicate many APIs for strings and byte arrays as it is the case in Go.
I’m not sold that they’ve actually solved the coloring problem vs given it a different syntax.
To be clear, the problem with C isn't macros, but text based macros. Syntax based macros are really good (as shown by Lisp and friends)
AST macros are very powerful. As to them being "good", that's debatable. They have advantages but also disadvantages. For one, they operate on syntax, so they're a separate metalanguage and not so pleasant to debug. For another, they are referentially opaque (i.e. when passed different expressions with the same meaning, they can produce different results), which makes them powerful but also mysterious.
What's interesting about Zig's comptime is that while it's strictly less powerful than AST macros, it can do a lot of what macros can do while not being a metalanguage - just Zig.
To be clear, we all know GP is talking about C macros.
Not only being text based but also having another separate language is problematic. Rust also has powerful declarative macros but it is it’s own language. Procedural macros and crabtime are imho a bit better for more complex cases as you write Rust.
> with lessons learned
A very small subset of possible lessons that could have been learned...
I've seen the custom allocators mentioned many times as central to the value proposition. Do the allocators shipped with the standard library compose the system allocator, or are they completely distinct from the *alloc family shipped as part of libc?
You can ofc use the *alloc from libc if you want. Otherwise there are different ones in the standard library, ArenaAllocator wraps another allocator, FixedBufferAllocator uses a given byte slice. I recommend to take a look at https://ziglang.org/documentation/master/std/#std.heap to get an overview.
Maybe read https://ziglang.org/ ? They list the goals:
and how they are trying to achieve that: simple language, and 'comptime' for metaprogramming (a more or less new approach). No, not really.I don't think it's a general-purpose programming language at all.
Great systems language though.
Zig’s undefined behavior story is not nearly as much of a minefield for one. That should be enough really. If you think the CPP is good enough for metaprogramming, I don’t know what to tell you either.
It's a language that attempts to solve more of the biggest issues with low level programming than any other current low-level programming language. Of course, there is nowhere near a universal consensus on what the biggest issues are, but here's what they are to me in order of importance (and I'm not alone):
1. Language complexity/lack of expressivity. You want code, as much as possible, to clearly express the algorithm at the level of detail needed at the language's domain, no more and no less. The level of detail in low-level languages is different from high-level languages because, for example, you want to see exactly where and when memory is allocated/freed. Both C and C++ fail at this for opposite reasons. C is often not expressive enough to express an algorithm clearly (at least not without the use of macros), and C++ is often too implicit, hiding important details that are then easy to miss [1]. These problems may affect program correctness.
2. Lack of spatial memory safety, which is the cause of the #2 and #6 most dangerous software weaknesses (https://cwe.mitre.org/top25/archive/2024/2024_cwe_top25.html). Unlike spatial memory safety, Zig doesn't guarantee the lack of temporal memory safety. This would have been very nice to have, but it isn't as important and not worth compromising on the other top points.
3. Slow build times, which may also affect correctness by slowing down the test cycle.
I don't find Zig similar to C or C++ at all (certainly not as similar as Rust is to C++). If anything, Zig's risk is in being a more revolutionary step than an evolutionary one.
---
[1]: In the late eighties/early nineties (when I first learned C++), when we thought it might be a good idea for a language to be both low-level and high-level, C++'s notion of "zero-cost abstractions" seemed very interesting and even promising (I don't recall them being given that name then, but the problem - or advantage - was right there at the beginning; e.g. whether a call uses static or dynamic dispatch is an algorithmic detail that may be of interest in low-level programming, as well as whether a destructor is called, possibly through dynamic dispatch). Now that notion feels an outdated vestige of a bygone era. I'm aware there are still C++ programmers who still believe in writing high level applications in low-level languages and still believe in zero cost abstractions, but I think the industry has clearly been going the other way, and there's no indication it may be changing direction or may have any reason to do so.
> "zero-cost abstractions"
I believe that in modern times, this term refers to stuff like: transparent conversion to a low-level representation (e.g. a bit-packed integer) from a high-level, statically checked datatype - e.g. a tagged union with exhaustive pattern matching, aka ADT. This is also something C++ etc lack.
Check out Carbon, its the Kotlin of C++ ;)
I am not a C++ guy, but when Carbon is finally stable and hits the mainstream, I will definitely start trying out Carbon.
https://github.com/carbon-language/carbon-lang
The way I see it, it's for people who want a more modern C, but not C++.
There's not much languages in that space, essentially C3 and Zig, but the former is much less advanced IMHO (also in terms of tooling).
Odin
For me its simply better C, and the stdlib is pretty well designed overall
Simpler, modern C with better tooling and less undefined behavior.
> Is it kind of like the Kotlin of C, going for a better syntax/modern features but otherwise being very similar?
For me that sounds like a rather good value proposition. Too bad Zig never got the stackless corountine part they promised in the start.
The value proposition of Zig is it's the most ergonomic way to do systems programming I've ever seen. First class allocators, arbitrary width integer types, top notch bindings to OS syscalls in the std lib without relying on libc, and you can translate C bindings to Zig at compile time, so no FFI layers for existing libraries.
They sometimes write about how they're a general purpose language, but I strongly disagree. It's unapologetically a systems programming language; that's it's entire focus.
It's a powerful alternative to Rust and C++ for writing ultra low latency code when safety isn't important, like games or HFT. Its standard library and ecosystem have excellent support for passing around allocators and no hidden dynamic allocation (every function that allocates takes an allocator as a parameter), which makes it much harder to hit the latency pitfalls common to Rust and C++. It also encourages the latency-optimal approach of using local bump-a-pointer arena allocators where possible rather than the slow global allocator. And finally, the superior metaprogramming support makes it more convenient to use high performance techniques like struct-of-arrays.
Rusty rust and C++-y C++ are both often slower than hand-rolled C for a given function, and zig is intended to be a better way to hand-roll some C.
C as a language is obsessed with the fact that C runs everywhere. Even on a DSP with a 24-bit char and a 24-bit int. If you take out those complexities and you add 40 years of lessons on language design, you can make something a lot simpler.
Rusty rust?
I don't think there is such a specific thing and certainly disagree that all idiomatic rust is somehow slower by default.
You can write rust like you might write a higher level language and then that can end up slower but if you write idiomatic low level rust, the performance is much harder to compare with C. There are things which will be faster in C and things which will be faster in Rust but broadly things will be extremely similar in performance.
I write bare metal embedded rust a lot these days and there are quite complex concepts you can represent in rust which make your code a lot safer without a performance hit.
Idiomatic "low level" rust clocks in at about 10-50% slower than hand-coded C every time I try it. It is also about 10x easier to write the Rust code. Unsafe is just required a lot of the time. Sometimes it's code size or struct size just being larger to express a similar concept. To get back your performance you have to do things that are un-idiomatic (but you have to do in C anyway).
That is an unbelievable claim.
1. Rust structs are generally smaller due to layout optimization.
2. A 10-50% difference is well within the “are you measuring debug builds?” territory.
I’m curious what code you are writing that requires unsafe all the time? I do a lot of low-level optimization, and unsafe is barely ever actually needed.
It sounds like you work with people who don't really know C. Understanding how to pack a struct is a pretty basic skill. Write an optimized database or network stack without unsafe for me.
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
I did not say “never”, I said “barely ever”.
I’m not really sure what your point is by linking the benchmarks game. I mean, it’s a fun activity, but this is saying nothing about C vs. Rust. It may or may not be saying something about GCC vs. LLVM.
Show examples please.
> Rusty rust and C++-y C++ are both often slower than hand-rolled C for a given function
This makes no sense whatsoever and very far from the truth.
"Safety" is always important, and you can write safe software in Zig.
“Safety” as defined in the context of the Rust language - the absence of Undefined Behavior - is important 100% of the time. Without it, you are not writing programs in the language you think you are using.
That’s a convoluted way to say that UB is much, much worse than you think. A C program with UB is not a C program, but something else.
curious, where is the definition of "undefined behavior" for rust specified?
Here: https://doc.rust-lang.org/reference/behavior-considered-unde...
Your comment was corrected or written by ChatGPT, right? It's super interesting that I can recognize these things now. The specific usage of punctuation, certain words and sentence construction.
Safety not important in HFT? You'd better make sure those precious microseconds buy you enough to make up for when things go awry.
Also, modern online gaming with microtransactions isn't something I'd entrust to "hold my beer" languages and gaming industry development practices.
Crashes from safety bugs are rare in HFT because they can replay years of data against code changes. For a strategy that trades in and out of positions quickly and is flat most of the time, it's also often not a big deal if the program crashes in the midst of running, as long as some technique has been arranged to cancel resting orders and alert a trader (who is generally monitoring the system's operations at all times).
They're certainly not inclined to pursue safety at any expense of performance in their code.
> modern online gaming with microtransactions
I don't think anyone should develop such games either
>Safety not important in HFT? You'd better make sure those precious microseconds buy you enough to make up for when things go awry.
Memory safety bugs are very rare in modern, well-written and tested C++. The key difference is that there are no adversarial inputs, while something like a browser or server needs to deal with potentially adversarial inputs, making absolute memory safety much more important (as even a single memory safety issue could be exploited).
Being the anti Rust alternative for people who has spent years/decades accumulating weird knowledge about the inner workings of C and/or C++ and maintain that being able to shoot your feet off at a distance when doing the wrong incantation is a critical feature to have.
I’m ranting but based the Rust/Zig discussions here on HN and the number of segfault issues in the Bun repo there is a core of truth.
https://github.com/oven-sh/bun/issues?q=Segfault
Or Rust being the anti Zig alternative for people who have spent years/decades accumulating weird knowledge about the finer details of type systems and maintain that not being able to express an algorithm, or review one, without consulting a language lawyer (or becoming one) is a critical feature to have and that build times don't matter.
The point is that all languages, including those two, make very clear and sometimes significant tradeoffs that may be more or less appropriate in different circumstances or for different people, and, at least so far, no consensus about the "right" tradeoff has emerged.
How is Rust anti zig if it came first?
It was a joke premised on the implicit assumption that Zig must be an "anti-Rust" because it came later. Maybe you could call different approaches contrarian if Rust had achieved some great popularity or consensus, but it hasn't. Rust's adoption rate is low because many don't find it enticing enough, and so it's unsurprising that there are several other approaches in the space of low-level programming - which is due for some update - that are all different from each other. Their attempts to improve on C and C++ in different ways don't make them "anti" anything else.
Ron Presler (the person you're responding to) is pathologically anti-Rust since before the birth of Zig.
Oh, I'm very pro Rust. I think that its use of the borrow checker is inspired and quite spectacular, that we can learn a lot from it. I just don't like it (as a practical programming language). It's not for me and for people who have similar preferences.
I am, however, very much anti claims made by some Rust fans that take an empirical and universal nature and are simply not known to be true (e.g. it is true that the more memory safety guarantees the fewer the vulnerabilities - all else being equal - but it is quite simply logically incorrect to conclude from that that the best way to minimise vulnerabilities is to have more sound safety guarantees).
I think Rust is a fantastic fit for some people who want to do low-level programming, and a pretty bad fit for others (like me). Same goes for Zig or, really, almost any language. Obviously, neither one is inherently or universally superior to the other.
BTW, my enthusiasm for Zig is not because I like all of its design decisions, but mostly because it's so different from most other languages and, in some cases, its decisions run contrary to my personal inclination (e.g. with regards to encapsulation) that I'm fascinated to know how it works out. Rust, on the other hand, is less interesting for me to think about, because aside from the more intensive typechecking (that I'm already familiar with from other languages) the overall experience it offers is quite similar to C++. Maybe I won't like what Zig ends up becoming, but for someone who's seen so many languages, it's really interesting to come across something so fresh.
There is plenty of room for both languages to exist. Engineering is all about trade offs. Rust has some big pluses but it's not suitable for every application.
To be fair, nodejs has 36 open, 474 closed:
https://github.com/nodejs/node/issues?q=Segfault
The question that matters is how many deno has.
Which is written in C/C++. Showing that Zig is not moving the needle on UB when a project becomes sufficiently complex.
Take a look at Deno and check the percentage coming from FFI with unsafe languages.
https://github.com/denoland/deno/issues?q=Segfault
People keep thinking that even though Microsoft, Apple, Google, etc. with all the incentive and tooling in the world couldn't evade one of the few replicable results in programming languages (people can't reliably write memory safe code in memory unsafe languages), somehow with Zig it will be different. It's honestly a pretty fascinating phenomenon to me because most of these people are smart, and some of them are even ostensibly in the security community.
We have language groupies now, like how teenagers have their favourite k-pop bands, I wouldn't take it all so seriously. Security has a tendency of making itself undeniable, it's lessons will be learned one way or another by everybody without exception.
Zig's pointless choice to avoid global constructors - something all platforms have supported for several decades by now - makes I/O extremely unwieldy. That alone prevents it from being a viable mainstream language.
There is a lot of useful technical work and ideas in it though.
Andrew Kelley (Zig creator) replied to this on lobste.rs
https://lobste.rs/s/js25k9/is_zig_s_new_writer_unsafe#c_ftgc...
What a terrible way to take constructive feedback.
Writing not one but two blog posts takes time and effort, moreso when it includes investigation and examples... the posts are not just low effort "this is crap" rants (and they even blame themselves, even though it's clear from the posts that there are documentation/discoverability issues).
What if the poster doesn't feel knowledgeable enough to contribute code? (as shown by his first post title, "I'm too dumb for...")
If that's not collaborating I don't know what it is...
That's not the read I got from Andrew's comment, or the situation. If the poster doesn't feel knowledgeable/able enough to collaborate in the community discussions (like the issue links, which don't require contributing code) then doing individual blog posts instead is only going to give even worse results for everyone.
Author here. I see it both ways.
Blog posts are collaboration (1). I did get the sense that Andrew doesn't see it that way. (And for this post in particular, and writegate in general, I have been discussing it on the discord channel. I know that isn't an official channel).
My reasons for not engaging more directly doesn't have anything to do with my confidence / knowledge. They are personal. The linked issues, which I was aware of, are only tangentially related. And even if they specifically addressed my concerns, I don't see how writing about it is anything but useful.
But I also got the sense that more direct collaboration is welcome and could be appreciated.
(1) - I'm the author of The Little MongoDB Book, The Little Redis Book, The Little Go Book, etc... I've always felt that the appeal of my writing is that I'm an average programmer. I run into the same problems, and struggle to understand the same things that many programmers do. When I write, I'm able to write from that perspective.
No matter how inclusive a community you have, there'll always be some opinions and perspectives which get drowned out. It can be intimidating to say "I don't understand", or "it's too complicated" or, god forbid, "I think this is a bad design"; especially when the experts are saying the opposite. I'm old enough that I see looking the fool as both a learning and mentoring experience. If saying "io.Reader is too complicated" saves someone else the embarrassment of saying it, or the shame of feeling it, or gives them a reference to express their own thoughts, I'm a happy blogger.
I don't even like Zig but I read your blog for the low level technical aspects. I agree completely that blog posts are collaborative. I read all kinds of blogs that talk about how computers work. I can't say if it brings value to the Zig people, but it certainly brings value to me regardless!
Author is posting honest and respectful critique of Zig features on their blog. That is a valid way of collaborating in the community discussion. The project github isn't the only place where discussion is allowed to take place.
The claim isn't you should shut down your blog and only talk on GitHub to be engaged with the community. Zig has tons of communities https://github.com/ziglang/zig/wiki/Community and, of course, blogs also play a part in the overall community too. Picking a single engagement option is probably always a poor choice, but that option being your personal blog alone would be one of the poorest. That's where the feeling of lack of collaborating with the community is coming from, not that they specifically don't engage in GitHub alone.
Make blog posts, it's great!, but if you don't think you're the expert then they'll go a lot farther for everyone if you put 5% of the work of doing so into engaging with the community about it for additional insights first. That's a fair note to make, though I agree the ending could be less passive aggressive about those who don't want to engage with the community.
FWIW as someone with only a pinky toe in the Zig community, it's quite engaging and interesting to see a blog post like this. It makes me want to learn more, and reminds me that there's a wide tent here (that might even include me!), not just a tight-knit "inside" group.
I think it's a reasonable response aside from the last sentence aside.
Is it reasonable in its entirety?
Might be cultural differences but, to me...
> Kinda wish the author would attempt to collaborate rather than write stuff like this [...] but, whatever, it’s their blog so they can do what they want.
...feels like passive aggression. In particular the "stuff like this" (like what?) and "but, whatever" felt very unnecessary and the whole "I wish he'd collaborate on my terms" is IMO uncalled for.
Yeah, I could see it being better without that portion of the final sentence. At the same time, I think opening "What a terrible way to take constructive feedback" is at least equally as grating a way to engage about it - but at the end of the day we're all humans, not saints, and it seems clear to me both comments are well intentioned and decently put as a whole. Same as me, I'm sure if I look back at these comments in 3 days there will be parts I would have changed, but overall I'd probably thing they were decent instead of terrible.
I'm glad you made the note about that part though, I agree with it and we can always do better.
I've read it completely differently.
The response IMO is constructive and invites the blog post author for further discussion.
I think it's likely that both the blog poster and the maintainer are being perceived as more negative in tone than the intent / reality. They both included disclaimers "I must be doing something wrong. And if I am, I'm sorry." and "whatever, it’s their blog so they can do what they want." They're also both giving critical feedback "But, if I'm not, this is a problem right?" "Kinda wish the author would attempt to collaborate rather than write stuff like this" but in both cases the criticism is extremely mildly worded compared to most toxic online discourse. This seems... great? Isn't it good we're able to disagree so politely? It's not toxic to have a disagreement or to give critical feedback. We don't need to all pretend to agree with each other all the time or be happy with each other in order to have a civil discourse.
"but whatever" are two of the most dismissive words when put together. "I see what you've written, but whatever."
It depends on context. When someone raises a potential objection and then says "but whatever" they are being dismissive towards their own objection. This is also called "letting it go" or "moving on".
And posting direct links to the places where discussion actually happens along with providing tldr context is as constructive as you can get. But whatever :)
Except, if you click on the Openmymind.net link on HN to show all its submission, it has been Zig focus critics on different things, and may be rants.
Collaborating would be contacting the Zig team through one of the many channels available and asking questions, offering suggestions etc. Posting critical blog posts without doing this first is counter-productive, and can even be seen as self promotion. After all, we're now discussing the blog posts, and not the actual issues. Would this have happened if the author had just sent an email to the mailing list or asked on Github?
Nah, this is absurd. This guy or anybody else can write whatever they want, whenever they want, on their own blog. They are under zero obligation to create bug reports, file issues, check in on a chat channel, or contribute in any other way to an open source software project that does not employ them. Writing blog posts is a perfectly reasonable and normal community behavior.
The members of the Zig project are free to reach out to the author!
When you create a project in public people will write about it, tweet about it, complain about it, etc (if you’re lucky!).
Intermernet said, "Posting critical blog posts [...] is counter-productive."
You said, "anybody [...] can write whatever they want". "They are under zero obligation ...". "Members of the Zig project are free to reach out ..."
Do you not realize that you have not at all addressed the point about what is the most productive way to criticize?
All you have done is go off about people's rights, freedoms, and lack of obligations. But nobody actually said "People shouldn't be able to post critical blog posts" or "People are obligated to participate by filing issues or contributing code to open source". So what was the point in saying this? Do you think people believe anything contrary to what you said?
The parent quite literally made a normative statement and I disagreed with it:
If nothing else, this is attempting to define what counts as valid collaboration, and it's a definition I reject, so I disagreed with it. Good-faith experience reports are valid, useful, pro-social collaboration. Doing so is a perfectly productive way to criticize. Apparently they do. The parent even made a veiled accusation that the author writing a good-faith blog post on their own blog about their own experiences "can even be seen as self promotion". Since when is sharing your good-faith critique about the design of a tool you've used something underhanded or nefarious?Setting the bounds of valid community collaboration to "people can post on their own blog as long as I like it otherwise they're being mean" is not a set of values I subscribe to, so I felt it was worth it to articulate that.
Why is this counter-productive and self promotion? Does that mean we should all stop writing programming related blog posts? And move all the discussions into GitHub issues only?
This reads to me like an attempt at polishing a pig.
Just hide all issues people using your project stumble upon in internal mailing lists and project a polished facade.
This reads like an issue anyone can stumble upon with the answer being ”you’re holding it wrong”.
I want to find that from a quick search rather than wading through endless internal discussions.
Andrew wrote ONE SENTENCE and that's enough for you to diagnose him? That's enough for you to identify a pattern of behavior? Really?
He's "polishing a pig"? He's hiding "all issues" with Zig in internal mailing lists to "project a polished facade"? ALL?! You got all that from one sentence saying he wishes the author took a different approach?
Alright, fine. Here's my analysis of your character and lifelong patterns of behavior based on your first two sentences:
You just want to tear down everybody who is trying to do good work if they make any mistake at all. You look for any imperfection in others because criticizing people is the only approximation of joy in your existence. You are the guy that leaves Google reviews of local restaurants where you just critique the attractiveness of the women who work there. You see yourself as totally justified and blameless for your anti-social behavior no matter the circumstances, and you actually relish the idea of someone being hurt by you because that's all the impact you could hope for.
If that's not accurate to who you are, well, ¯\_(ツ)_/¯ that's just how it reads to me.
I am not talking about Andrew? I am sorry if that was not as clear as it needed to be.
Not sure where the tirade came from?
I am talking about the person responding here trying to decry OP for not hiding away his issues in internal communication channels.
> Kinda wish the author would attempt to collaborate rather than write stuff like this and I’m too dumb for Zig’s new IO interface but, whatever, it’s their blog so they can do what they want.
Damn, Andrew Kelley really come across as a dickhead when taking any bit of criticism about his language, often painting them as bad actors trying to sabotage the language.
This isn't the first time he repeats this behavior.
EDIT: https://news.ycombinator.com/context?id=45119964 https://news.ycombinator.com/context?id=43579569
Yeah, and his behavior in this LLVM discourse thread made me not want to ever try Zig: https://discourse.llvm.org/t/rfc-libc-taking-a-dependency-on...
That all seemed pretty adult and tame. Maybe slightly stand-offish at worst. And I tended to agree with Andrew in that thread. A project like Zig is an absolutely massive undertaking. I can cut Andrew some slack. Not everyone is perfect all the time, and his behavior there was nowhere close to BS I have seen in other open source projects. Ahem, Linus.
Did you read until the end of the thread? I was thinking the same at first but only because it took awhile for the conversation to play out.
From my plain reading he didn't take time to understand the proposal before providing feedback. That's fine as far as being busy or miscommunication goes, it happens, but after it was pointed out he never apologized or offered more constructive feedback. Which again is fine, but I'd expect a technical leader to not isolate the maintainers of their most critical dependency. Clearly he gave them a terrible first impression.
I'm guessing you never tried Linux either
Just because a popular project leader is a jerk does not mean the way to success is to be a jerk too.
Sure, but the evidence suggests that a complete inability to deal with jerks is going to be very limiting.
Maybe for some people. But most people are not jerks and you can absolutely limit yourself to dealing with them only.
Unless you want to participate in your HOA or local government, then I can't see how to limit myself to dealing with only non-jerks.
> any bit of criticism about his language
I'm not even sure that it's criticism. I read it as a genuine open question.
At least in my experience, asking questions like this through GitHub issues or a mailing list are met with negativity. I don't want to post through a channel where I'll get a snide, terse response from a maintainer. I'd much rather post to my blog audience, who I find to be generally knowledgeable and friendly enough to already be following me. And if I found an answer, I'd post about it and explain what I learned in the process, linking from the existing post.
In a lot of ways, I think Andrew's response is exactly the sort of flavor of reply that I would have expected no matter what channel the question had been posed through, and that's exactly why I wouldn't have gone through those channels if I was the author. His reply didn't answer the question aside from implying it's maybe an issue, nor did it invite feedback.
That was not my takeaway from his comment at all.
Quite. I don't think it's unreasonable to expect someone to check the issue tracker before blogging and I don't think Andrew's response was at all problematic.
I'd say the only issue what the "too dumb, but whatever" comment.
That should have been removed and it would have been totally reasonable.
Edit: Oh actually, the author has another blog post titled "I'm too dumb for Zig ...". With that context, it makes sense and I agree it's a reasonable response. I'm sure other readers like me didn't know that context though.
Nothing wrong/strange in those posts.
In any case I've seen how communities treat the authors of important projects that touch their livelihood or habits to be unsurprised an author may lose it at times.
Idk, Andrew's comment seems fair enough to me.
yup, he's also got a consistent history of aggressively disparaging and misinformed comments about go, fwiw
Andrew may be expressing frustration or dismay or annoyance in that statement, but he is not definitively "painting them as bad actors trying to sabotage the language". You are HEAVILY reading into his statement.
He only said he wishes the author would have taken a different approach. So what? Why does everyone have to jump in and start psychologizing or essentializing Andrew based on one paragraph?
Why does one paragraph have to say so much about who he is as a person? Even if it did piss him off for a few hours, so what? He's not allowed to wish someone took a different approach?
I tend to think Andrew Kelley is a great guy, not just technically but as a person. And I think that because I've listened to him talk for dozens of hours. I can guarantee you that that one sentence he wrote is not the beginning of a character assassination campaign against the author of this blog.
He made Zig because he wanted to put something good into the world and improve the state of software. How about we include that in our analysis of Andrew's character? I'll leave it to the reader to consider whether the multi-year full time dedication to Zig should be weighed more heavily than a personal feeling he had for two minutes that he expressed respectfully without attacking anyone's character.
From his "Open Letter to Everyone I've Butted Heads With":
> My friend - it's not personal. I care about you. I actually do value your opinion. I'm interested in your thoughts and feelings. I want to make you happy. I'm sad that I can't serve you better with my open source project. I want to. I wish I could.
> I'm hustling. I'm playing the game. I'm doing what it takes to make this thing mainstream and a viable, practical choice for individuals and companies. If you talk shit about Zig in public, I'm going to fight back. But I respect you. I see you. I understand you. I don't hate you. I would literally buy you a drink.
https://andrewkelley.me/post/open-letter-everyone-butted-hea...
I know what you mean, but name-calling has got to be one of the worst ways to call for some decorum. It just leads to flame wars. (Be the change you want to see, and all that.)
EDIT I totally missed the context
Read the comment I replied to.
edit: np :)
My bad :)
Interesting. I liked the candid honesty.
Who cares? seems like something for the issue tracker no?
The blog author has a history of posting clickbait'ish criticism about Zig.
Right, that huge series he wrote as an introduction to Zig and all the articles about specific Zig features were super mean and clickbaity...