Hacker News new | ask | show | jobs
by Scarbutt 3662 days ago
Rust reduces the amount of state I need to keep track of in my brain.

I doubt it, the mental overhead of doing "safe memory programming" in Rust is very high.

Edit: all good replies, want to clarify and forgot to mention that I was comparing to languages with a GC, since I'm seeing Rust being used for lots of stuff, in a general purpose programming language sense (like creating web frameworks for example). Also, for non-very-low-level stuff I guess this cognitive load will be less if/when they introduce an optional GC.

6 comments

Designing memory-safe programs in C requires a programmer to reason about the same domains as doing so in Rust, but C doesn't double-check you to make sure you get everything right. With no guard rails, C is a lot more stressful.

Re: reducing mental state for a programmer, algebraic datatypes in general decrease the size of the state space of your program by making many illegal states unrepresentable. Without advanced forms of dependent types (maybe quotients), you can't make all illegal states unrepresentable, but you shrink the size of the state space hugely compared to writing everything as product types (as you would in C). A programmer has to reason about all the possible values their variables can take on, so it pays to minimize the cardinality of that set.

So what actually happens is that you develop habits to enforce invariants that lead to correct operation. This isn't nothing, but it's also good practice in other languages and the more you do it, the better you get at it and the less stressful it is.
Why are we throwing away all the work done on static & dynamic analysis tools for C programs in this kind of discussions? Programmers are crippled just for picking C? Come on..
The benefits of advanced static and dynamic analysis tools for C shine through on questions of semantic correctness (look at Coverity, Frama-C and PVS Studio), not memory safety (though they do reason about memory safety). You can achieve perfect memory safety (no false negatives and arbitrarily few false positives if you write appropriate abstractions around unsafe) with comparatively simple static analysis built into your compiler... but only if your language is designed to permit it.

In C, perfect static analysis for memory safety is impractical, and dynamic analysis is time-consuming and cannot preclude false negatives. We should work on porting tools which heuristically warn about semantic correctness concerns from operating on C to checking Rust programs, and this is probably necessary in order for some C or C++ programmers/projects to switch, but it doesn't pertain to the question of how much mental overhead there is to writing memory-safe code in either language.

Because ultimatelty they're imperfect.

Sure, C+static analysis is good enough for many situations. But it can't compare with the guaranteed safety offered by Rust.

> Because ultimatelty they're imperfect.

Everything is imperfect, it's not a good reason to discount anything.

I don't remember the source.. but somewhere someone said that the borrow checker would get in the way until you've learned to a certain point, then after that point developers tend to think in terms of the borrow checker by default and it _works for them instead of against them_.

Besides, you're still going to be doing safe memory programming regardless of whatever language you use. (unless you're just saying "writing broken code is easier")

This is consistent with a lot of people's experiences with Rust. Some people haven't even noticed when the mental bit flipped for them, "Oh wait, I just realized I haven't fought the borrow checker in a while..."

Of course, some people still don't like it. Not every language can be to everyone's liking, a plurality of languages is a good thing. Plus, we do have some stuff in the pipeline to increase the number of programs the borrow checker will understand; some people can get frustrated when they want to write a valid program that gets rejected, but this is going to be the case with any kind of static analysis.

The mental overhead of doing "safe memory programming" is high already. The difference between Rust and, say, C, is that Rust forces you to do "safe memory programming". C lets you get away with unsafe memory programming.
C lets you deliberately do unsafe memory programming, which is maybe OK if you actually know what you're doing. But C also lets you think that you're doing safe memory programming, when that is not the case.
Not my experience, fwiw. Rust does a great job of handling the mental overhead (am I allowed to mutate this? who owns this? what is the contract for that?) for me.
Exactly. Compiler-enforced ownership and lifetimes _dramatically_ reduces the mental overhead of memory management compared to C. It also saves time from having to run things under Valgrind and ASAN just to make sure I didn't mess up. The extra time spent getting Rust code to compile is considerably shorter than the time required to debug something Valgrind found.
I feel the same way about C++ smart pointers, which are remarkably simple to use and understand.
While definitely an improvement over raw pointers, ultimately C++'s smart pointers still fall short in several ways: they can be null, there's no lifetime checking for references (so you can still use after free), there's no object freezing (so you can still have data races), etc.
Exactly. Compiler-enforced ownership and lifetimes _dramatically_ reduces the mental overhead of memory management compared to C. It also saves time from having to run things under Valgrind and ASAN just to make sure I didn't mess up.
This is basically why I ditched Rust as soon as I found out about Nim. No mental gymnastics making me feel like I should be part of a group mind, super fast, super small binaries, optional GC, and memory unsafe stuff allowed with standard pointers and alloc/free available with or without the GC on elsewhere. I suspect Rust would be better for avionics and other high-value systems though, replacing Ada...
I like nim for the same reason (and use for for small programs), though I'm using D at $work because D is more "mainstream" and established at this time.
Can you give some examples?