News for hackers. Stuff that matters.
Re:Experts vs. Imitators by kragen on Sunday June 16, 2024 @05:55PM (#40700448)
it's somewhat true, though; python is vulnerable to concurrency errors that rust isn't (rust's concept of safety isn't just memory safety), and while python can detect type errors reliably at run time, that only makes the program fail in a way that is easy to debug and probably won't corrupt your data. for many purposes that is not an adequate substitute for detecting the problem at compile time so that it cannot fail at run time

on the other hand, python is more productive than rust, so if you're time-constrained, sometimes using python will get you a higher-quality product, for example because it's better tested or has a less error-prone or more forgiving user interface. both python and rust fail only at run time when they detect index errors, and users can make dangerous errors with any potentially dangerous program

on the gripping hand, rust runs enormously faster than python, and sometimes optimization trades off against testing time and ui iteration time in the same way that writing more code does, and while writing python is faster, reading it often isn't, so there may be some size of program above which python has no advantages

so i think it's better to say that the question is based on an oversimplification rather than an error. to explain this to a layman i would probably tell some stories of programmers working late nights and delivering unusable guis

Re:Experts vs. Imitators by tomp on Sunday June 16, 2024 @07:53PM (#40701088)
There are no concurrency errors in Python.

Every bytecode instruction is implicitly wrapped in a lock.

Of course, you could still get semantic errors by locking the wrong things at the wrong time; but you can do that in Rust as well.

Re:Experts vs. Imitators by kragen on Sunday June 16, 2024 @07:55PM (#40701097)
those semantic errors are what i'm talking about, not bugs in the interpreter! rust's borrow checker rejects such 'data race conditions' at compile time (though there are ways to explicitly opt out of it)
Re:Experts vs. Imitators by tomp on Sunday June 16, 2024 @08:08PM (#40701178)
You’re either mixing stuff up or need to be more precise in your communications.

A “data race” is simultaneous access of memory from multiple threads, where at least one access is a write. It’s undefined behaviour in modern compilers (including LLVM therefore Rust).

Rust prevents that (except unsafe), as does Python.

All “semantic” concurrency bugs that can be written in Python can also be written in Rust.

Re:Experts vs. Imitators by kragen on Sunday June 16, 2024 @08:48PM (#40701359)
that's a correct definition of a data race at one level of abstraction, although the definition of 'simultaneous' required to make it a correct definition is broader than the one you're using; the relevant definition of 'simultaneous' is hairy, but in the case of two threads making a single access each, it is that either thread can be first. it doesn't require the accesses to literally happen in the same clock cycle

another definition of a data race condition is that it's a case where different interleavings of thread accesses to shared data produce different results. see https://en.m.wikipedia.org/wiki/Race_condition for more details and background on the concept

such bugs can be written in rust with unsafe, but not without it

hmm, thinking about it more, i wonder if what i'm saying makes sense

Re:Experts vs. Imitators by hansvm on Sunday June 16, 2024 @11:27PM (#40702073)
What you're saying makes sense, but I still don't think it's right. Imagine the classic broken bank-balance update algorithm from concurrency 101. It's safe Rust to individually wrap every operation with a lock instead of wrapping the entire transaction [0]. Both Rust and Python prevent data races as narrowly defined by the Rust docs [1], but semantic bugs like that can easily sneak in to your code if you aren't careful.

Not to mention, Rust chose not to do anything about the memory fence problem. You're probably mostly fine on x86, but acquire/release semantics and all that nonsense still apply when writing concurrent algorithms in Rust (you'll often get lucky if you have something like a queue/channel and use message passing, since implementations of those often have a few fences internally, probably the fences you need for semantic correctness in your own algorithms). You're a lot more likely to see that sort of problem crop up in embedded work.

[0] That's obviously a bad idea, but more intricate concurrent algorithms are tricky to write in Rust for the same reason they're tricky to write in other languages. You get a bit of help from the compiler which you wouldn't really in Python if you design things to leverage the type system and prove the invariants you need to uphold, but the compiler doesn't know about any of those invariants aside from data races.

[1] https://doc.rust-lang.org/nomicon/races.html