▲ | ajross 3 days ago | |||||||
> 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. | ||||||||
|