Remix.run Logo
ajross 3 days ago

> Seasoned Rust coders don’t spend time fighting the borrow checker - their code is already written in a way that just works.

That hasn't been my experience at all. At best, the first version of code pops out quickly and cleanly because the author knows the appropriate idiom to choose. Refactoring rust code to handle changes in that allocation idiom is extremely expensive, even for the most seasoned developers.

Case in point:

> Once you’ve been using Rust for a while, you don’t have to “restructure” your code to please the borrow checker, because you’ve already thought about “oh, these two variables need to be mutated concurrently, so I’ll store them separately”.

Which fails to handle "these two variables didn't need to be mutated concurrently, but now they do".

simonask 3 days ago | parent | next [-]

This is an interesting comment, because you point directly at the exact reason Rust’s approach is so productive.

In the C/C++/Zig code, you would add the second concurrent access, and then start fixing things up and restructuring things - if you, the programmer, knew about the first access, and knew that the concurrent access is a problem.

In countless cases, that work would not be done, and I cannot blame any of the involved people, because managing that kind of detailed complexity over the lifespan of a project is not humanly possible. The result is another concurrency bug, meaning UB in production.

Having the compiler tell you about such problems up front, exactly when they happen, is a complete game changer.

ajross 3 days ago | parent [-]

> In the C/C++/Zig code, you would add the second concurrent access, and then start fixing things up and restructuring things

Well, sure, which in practice means throwing a lock around it.

I mean, I get it. There's a category of bugs that happen in real code. Rust chooses some categories of bugs (certainly not all of them) to construct walls around and forces code into idioms that can be provably correct for at least a subset[1] of the bug space. For the case of memory safety, that's a really pretty convincing case. Other areas are less clear; in particular I'm not a fan of Rust's idea of threadsafety and don't think it fits what actually performance-parallel code needs.

[1] You can 100% write racy code with Sync/Send! You can write racy code with boring filesystem access using 100% safe rust (or 1980's csh code, whatever), too. Race conditions are inherent to concurrency. Sync/Send just protect memory access, they do nothing to address semantic/state bugs.

simonask 2 days ago | parent [-]

This is true out of the box - Rust isn't magical, and it can't fix all your bugs for you. But it does make its own tools available to you, an API designer. Lifetimes are available to you without ever making any actual references, and the Send/Sync traits are available to you without constructing any standard synchronization mechanism.

You can construct something like `PhantomData<&mut ()>` to express invariants like "while this type exists, these other operations are unavailable". You can implement Send and/or Sync to say things like "under these specific conditions, this thing is thread safe". These are really powerful features of the type system, and no other mainstream language can really express such invariants at compile time.

ajross 2 days ago | parent [-]

Again though, I don't see a lot of value there. You seem to be implicitly repeating the prior that rust prevents race conditions, and it emphatically does not. It detects and prevents concurrent unlocked[1] access to a single memory location, which is not the same thing. Real races are much more complicated than that and happen in the semantic space of the application, not the memory details (again, think of email lockfiles as a classic race that has nothing to do with memory at all).

[1] Though with overhead. It's tends not to be possible in safe rust to get it to generate code that looks like a pthread_mutex critical section. This again is one of my peeves, you do dangerous shared memory concurrency for performance!

mattwilsonn888 3 days ago | parent | prev [-]

I would be interested to read the debates that stems from this point.