Comment by munificent
1 year ago
Board games and craft beers are utterly unrelated objects who have commonality on essentially no axes (except sitting on tables, I guess). And, yet, if you like one, there's a very good chance you like the other.
I think that's where the sentiment comes from. It's not that Rust is similar to C++ in terms of the actual languages and their features. It's that people who like C++ are morely likely to like Rust than people who like C are.
I would argue that C is not a minimalistic language either. There is a lot under the hood in C. But it feels small in a way that Rust and C++ don't.
I think Rust and C++ appeal to programmers who are OK with a large investment in wrapping their head around a big complex language with the expectation that they will be able to amortize that investment by being very productive in large projects over a large period of time. Maybe sometimes the language feels like trying to keep a piece of heavy duty machinery from killing you, but they're willing to wrestle with it for the power you get in return.
The people who are excited about Zig and C wants something that feels more like a hand tool that doesn't demand a lot of their attention and lets them focus on writing their code, even if the writing process is a little more manual labor in return.
> And, yet, if you like one, there's a very good chance you like the other.
Among my friends I know several people who are very enthusiastic about board games and several who are very enthusiastic about craft beer, but there's not a particular noticeable overlap. Personally of course I am very into board games and I don't drink at all.
> I would argue that C is not a minimalistic language either. There is a lot under the hood in C.
Nah, C actually is small, that's why K&R is such a short book. It makes enormous compromises to pull that off, but presumably on a machine where 64kB of RAM is extraordinary these compromises made lots of sense. C23 is quite a bit bigger, for example "bool" is now an actual type (albeit implicitly convertible) but still small by modern standards.
There really isn't that much "under the hood", it's often just the least possible moving parts that could possibly have worked.
a[b] in C++ is a call to a member function a.operator[](b) -- arbitrary user code
a[b] in Rust is a call to core::ops::Index::index(a, b) or, in context IndexMut::index_mut -- again, arbitrary user code
a[b] in C is just a pointer addition of a and b - one of them will be converted to a pointer if necessary, and then the other one is added to the pointer using normal pointer arithmetic rules
> Nah, C actually is small,
I'd argue that C is much bigger than K&R, but that isn't immediately visible to a new programmer because it's all undefined behaviors.
C23 + compiler extensions versus K&R C, is a little more than only UB.
Except C in 2025 isn't K&R C, rather C23.
Also even between C89 and C23, many folks wrongly count "whatever my compiler does" as C, and there are endless amounts of extensions to be aware of.
Exactly. There are two kinds of programmers, those who enjoy spending a bunch of time thinking about problems and decisions the language has foisted upon you (subtyping hierarchies, lifetime annotations, visibility, design patterns) and there are those that like spending that time thinking about the actual problem they want to solve instead.
I jest, but only a tiny bit. The features of heavy OOP and feature-rich languages tend to show their value only in really large codebases being worked on by several different people—precisely because many of their features are just guardrails to make it hard for people to code incorrectly against another's understanding or assumptions, when shared understanding is more difficult to establish. Contrarily, any solo programmer or really small team is almost invariably better served by a language like go, C, scheme, or Zig.
The idea that memory safety is only, or primarily, a problem in large codebases written by a sizable team is an interesting theory (sort of an inverse Linus' Law?) Unfortunately, it's contradicted by decades of experience.
Just to be clear, I liked memory handling in Rust. It was the sheer size of the language that made it... not fun. But borrow checker made sense.
Go is pretty good for large, shared projects too - thanks to its tooling, formalized best-practices and comprehensive batteries-included standard library.
That is simply not true. The bigger the project gets the more you see the shortcomings of go. You can see that very well in the k8s project
2 replies →
> Maybe sometimes the language feels like trying to keep a piece of heavy duty machinery from killing you, but they're willing to wrestle with it for the power you get in return.
It's funny because to me there's an analogy with heavy machinery but materially different: there are some industrial machines that have two buttons that need to be actuated to activate the mechanism, separated by arm length in order to ensure that the operator's arms are out of the way when the limb crunching bits are moving. I see Rust that way, engineering the safe way to do things as the path of least resistance, at the cost of some convenience when trying to do something "unsafe".
Okay, but now imagine a kitchen appliance that did the same thing. It would not be a big seller. Of course a kitchen appliance can injure and even kill you, but it probably wouldn’t unless you try really hard.
Most of programming is like that, but in the few cases where there literally are lives at stake, memory safety by itself will not do much for you and performance is going to be a secondary concern.
Zig does have safety features that C/C++ do not have, but also one should not underestimate the security implications of language complexity by itself.
The reason I focus on the memory safety difference is precisely to not minimize its importance. It's far more salient of a difference than whether a language "feels big" or not. Talking about whether Zig requires "a little more manual labor" than Rust is missing the enormous elephant in the room.
I think the people who like Rust are in a room where they perceive that elephant to be enormous and people who like Zig are in a room where they perceive it to be much smaller.
You can certainly argue whether or not their perceptions are correct, but I generally believe that people are entitled to their priorities.
Either way, you initially stated confusion about why people stated certain opinions about Rust, C++, and C. I tried to explain why people might hold those opinins. You are then arguing that they shouldn't hold those opinions. Whether or not that's true, a prescriptive claim is orthogonal to understanding what's actually in their heads.
The elephant is enormous, because the C crowd is not living up to what they need to do to actually make the lack of memory unsafety unimportant. C is like ruby in the sense that the untyped nature of ruby might initially buy you a productivity win, but in the long run it requires you to dilligently write impeccable unit tests, since even the most basic correctness checks can only be done at runtime.
Actually that's wrong. In C you will need exhaustive formal verification, because UB doesn't cause minor miscompilation anymore. Formal verification is far more onerous than whatever Rust is demanding.
> It's far more salient of a difference than whether a language "feels big" or not.
You clearly don't like it, but it seems many people disagree.
pcwalton is responsible for a lot of the rust borrow checker, so, not a neutral opinion. ive posted it too many times on this thread but it seems borrow checking analysis may be possible for zig (if the zig team should want to)
3 replies →