4 ms·
> intermittently doesn’t work in weird and impossible to debug ways This is my major reason for using Rust. It's far better to beat your head against a wall wh
by lordnacho 5y ago
> intermittently doesn’t work in weird and impossible to debug ways
This is my major reason for using Rust. It's far better to beat your head against a wall when you're writing than when you're debugging. In both c++ and c# it's possible to write subtly wrong code that is basically undebuggable. Often these are intermittent things that show up once every million or more runs. There's no amount of time that will satisfy you after you've run into this, even after you've fixed the problem. It's like having a stalker, you never know if they've stopped stalking you. You can lock your doors, you can buy an alarm system (eg Valgrind suite). But you won't know whether you've really solved the issue.
Of course it's possible there will be other undebuggable issues with Rust, I'm going more by reputation and general impression in blogspace rather than a thorough study. But I thought it was worth a try, and I've been positively impressed thus far.
- tialaramex 5y agoOne of the very particular "undebuggable" issues (safe) Rust solves is data races. Experience tells us that humans can't successfully reason about non-trivial concurrent programs unless they exhibit Sequential Consistency. In Rust you're promised this is what you get. Maybe what you wrote is stupid and wrong, but it has Sequential Consistency. "Oh," you exclaim during debugging, "A might happened before B and then we're in a pretty pickle" - you found the bug, now you just need to fix it. This promise is delivered by never allowing code to have references to things some other code might change, thus eliminating data races. In most other languages that offer concurrency this promise only applies if you wrote a program with no data races and the responsibility to ensure that is with you, so you can accidentally write programs that don't have Sequential Consistency and thus... "Wait, so, A happened before B and B happened before A? Huh? I don't even understand the bug".
- pjmlp 5y agoOnly for data races via threads on the same process, it does nothing to prevent data races via shared memory using IPC mechanisms across processes.
- tialaramex 5y agoHow so? Obviously you can build an unsafe IPC mechanism with concurrent access, label it "safe" when it isn't, and then say "Look at this horrible mess, I blame Rust" but it seems like it'd be faster to just implement std::ops::Index unsafely and then blame Rust because thing[len+1] blew up even though Rust has "memory safety". Now I'm going to write an amusing aside. One way you could get into this trouble is if your hardware allows arbitrary foreign memory writes as "IPC". The BBC microcomputer allowed this over the network! You could send a bunch of bytes over Econet (a 1980s network from Acorn Computers available for the BBC, Electron and Archimedes computers), addressed to another BBC micro on the network, asking they be written to a RAM buffer, and the remote hardware would do so. We used this to run a Multi-user Dungeon at school in about 1989 or so. A "server" ran the actual MUD software, and individual users signed in from a computer on the network around the school to play, when they typed a command their command buffer was transmitted over Econet, and then the server wrote remotely to their display RAM to show the result on their screen. Fortunately your computer is not a BBC Microcomputer, and foreign processes do not (on the whole) get to scribble on your program's memory. So this should not be a problem unless you specifically make this unsafe decision in your Rust program.
- pjmlp 5y agoBecause as explained on rustnomicon, there are many ways to access data in parallel ways, and the language only prevents a tiny subset of those cases. However almost every time data races and Rust come together in the same sentence it is as if it would prevent all use cases.
- tialaramex 5y agoBut (unless you've got an excerpt that says otherwise) the Rustonomicon is about unsafe Rust. And I was explaining that safe Rust has data race freedom. The Rustonomicon is not warning you about scary hidden problems in safe Rust, it's warning you about scary problems you need to care about when writing unsafe Rust, so that your unsafe Rust has appropriate safety rails before anybody else touches it. // Safety: Can't touch this while anybody else might write This reminds me of the mutex thing. Look at C++ std::mutex. You could implement exactly that in Rust. But, that's not what std::sync::Mutex is at all. Because if you implemented it in Rust, C++ std::mutex is either useless or unsafe and clearly we'd prefer neither. But do you have some examples of Rust shared memory IPC that you believe are unsafe? It might be instructive to either show why they're actually safe after all or, alternatively, go add the unsafety explanations and work out what a safe wrapper would look like.
- qalmakka 5y agoIf you are very zealous and use lots of C++17/20 magic, you can prevent lots of runtime bugs with C++ too by doing basically the same stuff you do in Rust (RAII, move semantics, use concepts, etc). Sadly that's not doable in C#.
- tialaramex 5y agoMove in particular is painful in C++ because to make it work C++ needs to invent these "hollowed out" objects that would be safe to deallocate after there's no longer a real value inside them. Rust doesn't need to do that. Suppose you've got a local String variable A. You will move A into a data structure which is going to live much longer and then your local function exits. In C++ when the function exits, A will get destroyed, so when A is moved into the data structure, A needs to be hollowed out so that whatever is left (a String object with no heap storage) can be safely destroyed on function exit. In Rust the compiler knows you moved A, therefore there is nothing to destroy at the end of the function, no work needed (at runtime).