Hacker News new | ask | show | jobs
by anon-3988 649 days ago
There's a huge gap between:

1. this is nasty 2. this is so much better 3. this is perfect

writing C is (1), most people claim that Rust is (2). (3) is utopia and anyone who claims that is not being honest.

I have seen this argument SO many times. I don't understand why this is so hard to understand? Do C folks use mmap directly instead of malloc? Does "safe" or "sensible" abstraction not exist in C? Do you use void* everywhere because "safe" abstraction like struct S* simply doesnt exist and if they do exist then "well, it could be wrong anyway so why not just give up?"

2 comments

The problem with manual memory management is that it makes safe and easy abstraction a lot harder. Every non-trivial function has a set of rules on who owns what that only exist in comments (or worse, in someone's head). Using the function wrong won't cause a compile error, but random unsoundness (that is sometimes data/dataflow dependent so pretty much impossible to sanitize for).
There is Rust code I saw that was cluttered with "unsafe block" to an extend that I am a bit skeptical there was meaningful memory safety left.. There is C code which is nicely structured where I have more confidence in. I am also skeptical about the overall complexity of Rust and I think cargo is "nasty" because of supply chain risk, proliferation of dependencies. So I do not believe for a second the gap between C and Rust so big Rust proponents want us to believe.
> There is Rust code I saw that was cluttered with "unsafe block" to an extend that I am a bit skeptical there was meaningful memory safety left.. There is C code which is nicely structured where I have more confidence in.

This is anecdotal but I have seen FAR more nasty C code than I have Rust. I can probably count using all my fingers and toes the number of times I have seen and have to vet unsafe code.

I spent a week vetting a WebSocket implementation in C to not have buffer overflows, memory leak, use-after-free, overflow, etc etc before I even start vetting the logic. They also have their own bespoke async library so I have to make sense of that first too.

I spent a day looking at WebSocket implementation in Rust exactly because I don't have to worry about stuff like is this void* reliable and following the call stack to make sure it makes sense.

> I am also skeptical about the overall complexity of Rust and I think cargo is "nasty" because of supply chain risk, proliferation of dependencies

I am curious how C solves this problem, if you need a btree, a JSON parser, a tree-sitter, a string with SSO optimization; where do you get this? Write your own? Vendor some packages? Rely on the package manager?

They all have the same issue of there's simply too many code to vet.

> They all have the same issue of there's simply too many code to vet.

The problem is not the amount of code to vet, it's the amount of people who own it, and thus the amount of people I need to trust.

In C, I use a "standard library" replacement like GLib or APR, and if they don't have what I need, then I implement it myself. Thus, the number of owners is just 2.

Is my own code less trustworthy? For a start, of course. But once I fix it, once a tool becomes stable, it stays fixed, in the face of all future dependency updates.

I don't see why you can't do this with Rust? If you want to use your own internet checksum implementation that doesn't draw in "random dependencies" for simd or whatever else. You are free to implement, verify and optimize your own.
It's not possible to do with crates.io because of the culture it has.

When I pull in GLib, APR, libuv, etc as a dependency, that is literally the only dependency. They depend on glibc, maybe libpthread/libm, and nothing else.

When I pull in tokio, I now have 40 dependencies.

I'm being a bit unfair to tokio, since they seem to actually be trying really hard to keep their dependencies down.

But I'll stick to my belief, as that seems more unusual than usual to me, for crates.io libraries in general. C has a culture of minimalism. Rust has a culture of easy of use. The latter is a nightmare for trust.

> There is Rust code I saw that was cluttered with "unsafe block" to an extend that I am a bit skeptical there was meaningful memory safety left..

There certainly is. But is it more than 1% of the Rust code out there?

And let's assume we're talking about a project where it is more than 1%. Let's say there's only 50% safe code (I personally have never seen this, not even in embedded). Is that still not a strict improvement over C?

> I am also skeptical about the overall complexity of Rust

When you're building a small project, using something like C++ or Rust will indeed feel like that.

But when you're building a large project, then using a simple language doesn't make things simpler... it simply moves the complexity elsewhere, and more specifically, into your code.

In that case, consolidating the complexity into a single place (the language) makes it so that this complexity is reusable, you learn it once and you understand all places that use it, even in other projects.

The time it takes to learn, yes, it'll be huge. Afterwards, programming in Rust becomes significantly easier than in C.

> I think cargo is "nasty" because of supply chain risk, proliferation of dependencies.

This one I actually really agree with, and am very sad about it.

I invite you to look at how close the C proponents think the gap is.