8 ms·
The sad thing is that most languages with threads have a default of global variables and unrestricted shared memory access. This is the source of the vast major
by norir 1y ago
The sad thing is that most languages with threads have a default of global variables and unrestricted shared memory access. This is the source of the vast majority of data corruption and races. Processes are generally a better concurrency model than threads, but they are unfortunately too heavyweight for many use cases. If we defaulted to message passing all required data to each thread (either by always copying or tracking ownership to elide unnecessary copying), most of these kinds of problems would go away.
In the meantime, we thankfully have agency and are free to choose not to use global variables and shared memory even if the platform offers them to us.
- zozbot234 1y agoMessage passing can easily lead to more logical errors (such as race conditions and/or deadlocks) than sharing memory directly with properly synchronized access. It's not a silver bullet.
- umpalumpaaa 1y ago100%. Some more modern languages - eg. Swift – have "sendable" value types that are inherently thread safe. In my experience some developers tend to equate "sendable" / thread safe data structures with a silver bullet. But you still have to think about what you do in a broader sense… You still have to assemble your thread safe data structures in a way that makes sense, you have to identify what "transactions" you have in your mental model and you still have to think about data consistency.
- kibwen 1y ago> The sad thing is that most languages with threads have a default of global variables and unrestricted shared memory access. This is the source of the vast majority of data corruption and races. Processes are generally a better concurrency model than threads Modern languages have the option of representing thread-safety in the type system, e.g. what Rust does, where working with threads is a dream (especially when you get to use structured concurrency via thread::scope). People tend to forget that Rust's original goal was not "let's make a memory-safe systems language", it was "let's make a thread-safe systems language", and memory safety just came along for the ride.
- tialaramex 1y agoOriginally Rust is something altogether different. Graydon has written about that extensively. Graydon wanted tail calls, reflection, more "natural" arithmetic with Python style automatic big numbers, decimal for financial work and so on. The Rust we have from 1.0 onwards is not what Graydon wanted at all. Would Graydon's language have been broadly popular? Probably not, we'll never know.
- nine_k 1y agoWhile at it, I suppose it's straightforward to implement arbitrary-precision integers and decimals in today's Rust; there are several crates for that. There's also a `tailcall` crate that apparently implements TCO [1]. [1]: https://docs.rs/tailcall/latest/tailcall/ https://docs.rs/tailcall/latest/tailcall/
- tialaramex 1y agoOh, I do know you can have arbitrary precision. I'm the author of realistic, which isn't "just" arbitrary precision it's an approximation of the computable reals as well, which is sometimes just enough more power than you'd hardly notice you have arbitrary precision too. https://crates.io/crates/realistic https://crates.io/crates/realistic
- kibwen 1y agoEven in pre-1.0 Rust, concurrency was a primary goal; there's a reason that Graydon listed Newsqueak, Alef, Limbo, and Erlang in the long list of influences for proto-Rust.
- fmajid 1y agoAnd yet it ignored the primary lesson of Erlang: no shared memory access whatsoever, which is what makes it so robust.
- littlestymaar 1y ago