Earlier quoted context omitted.
Sigh. We build machines to automate the repetitive, to eliminate the daily drudgery and to repeat steps with perfection (that we would repeat with perfection ourselves if only we were as focused as a machone). So why do we keep finding ourselves arguing that a lazy compiler, which offloads the work of a machine on to a dev team, is an acceptable compromise?
Meta-comment: I believe the difference in opinion here (which seems to recur, over and over, and has for decades) is because the job title of "software engineer" actually encompasses many different job duties. For some engineers, their job is to "make it work"; they do not care about the thousand cases where their code is buggy, they care about the one case where it solves a customer's problem that couldn't previousl…
Fearless concurrency with Rust
121–130 of 186 posts
Re: Fearless concurrency with Rust
#122Earlier quoted context omitted.
> The fact is, these "idioms and best practices" will not be followed perfectly on projects of any reasonable size if they are not enforced by code. Why would you not enforce them with code? Compiler shall not be an obstacle to a man. We tried enforcing things before, many times. Things got abandoned.
Agreed. But every production language that I'm aware of has an out that allows you to escape its type system, with the exception of languages whose type systems are intended to uphold strong security properties and verification languages that feature decidable logics. I can't remember for sure, but I think even Coq--which is eminently not a language designed for everyday programming--may diverge if you explicitly opt…
Re: Fearless concurrency with Rust
#123Earlier quoted context omitted.
Preventing deadlocks is not an unsolvable problem. Linear-session-typed process calculi are guaranteed deadlock-free and race-free. (The connection with Rust's ownership type-system makes me wonder if there might be some way to backport this guarantee to Rust, but I suspect the connection doesn't go far enough.) This comes at a price, however: certain process topologies are impossible to construct, and there's no way…
The safe subset of Rust (which is more-or-less linearly typed with elided drops) is indeed deadlock-free. Features like mutexes are written using the unsafe sublanguage because shared memory concurrency is useful. Because potential deadlocks are opt-in rather than opt-out, it's not unreasonable to imagine that future extensions to Rust (or some other language in the same mold) could bridge this gap in a practical way…
Of course, what you say is perfectly true, the Rust language itself has no threads or concurrency, and hence is automatically dead-lock free.
Re: Fearless concurrency with Rust
#124Earlier quoted context omitted.
The safe subset of Rust (which is more-or-less linearly typed with elided drops) is indeed deadlock-free. Features like mutexes are written using the unsafe sublanguage because shared memory concurrency is useful. Because potential deadlocks are opt-in rather than opt-out, it's not unreasonable to imagine that future extensions to Rust (or some other language in the same mold) could bridge this gap in a practical way…
FWIW, transitively-safe Rust is quite uninteresting as an actual programming language, since you can essentially only use some arithmetic and simple user-defined data types. There's no IO and no core data structures like Vec: `unsafe` is designed to be used as a building block to create safe interfaces and the distinction between safe things implemented in the language itself and safe things implemented in libraries…
Re: Fearless concurrency with Rust
#125everything mentioned can be done in C++11 and lthread_cpp http://lthread-cpp.readthedocs.org
What is interesting is not so much that Rust has shared-memory concurrency (BTW, isn't lthread a M:N threading library? Everything in the article is 1:1) but that it can make this statically safe. Perhaps I am missing something, but I see no evidence from your repository that lthread enforces any of the static safety guarantees discussed in the article, which is not surprising as many of them fundamentally depend on…
static safety guarantees can come with auto pointers (unique_ptr in particular). This is why I said lthread_cpp & C++11.
Re: Fearless concurrency with Rust
#126Earlier quoted context omitted.
What is interesting is not so much that Rust has shared-memory concurrency (BTW, isn't lthread a M:N threading library? Everything in the article is 1:1) but that it can make this statically safe. Perhaps I am missing something, but I see no evidence from your repository that lthread enforces any of the static safety guarantees discussed in the article, which is not surprising as many of them fundamentally depend on…
Possible M:N.. by default it's 1:1. It's 1 lthread scheduler per actual pthread. static safety guarantees can come with auto pointers (unique_ptr in particular). This is why I said lthread_cpp & C++11.
Re: Fearless concurrency with Rust
#127Earlier quoted context omitted.
Concerning std::allocator_traits, it reflects a deeper limitation of the language rather than just a library design flaw. If you had HKT, you could pass std::allocator to a template. You can't do that, you can only pass std::allocator for some concrete T. Equivalently, in Haskell, you can pass IO as a type parameter, so you don't see the same kludges. I definitely agree with the sentiment about subtype polymorphism.
You can actually pass std::allocator to a template: template foo {}; template class F> struct bar { F f; }; bar b; This is painful to do with a lot of the STL like vector, because they have a lot of default template arguments and there's no implicit currying. I haven't investigated it but variadic template template arguments might help there, though.
They do:
template class Container, typename T>
Container fin (T n) {
Container set;
for (T i = 0; i (10))
std::cout Re: Fearless concurrency with Rust
#128Re: Fearless concurrency with Rust
#129Rust's ownership model, and the borrow checker that enforces it, are a major breakthrough in language design. It's so simple, yet it solves so many problems. This is what Go should have done. Then Go's "share by communicating, not by sharing" would be real, not PR. Go code often passes references over channels, which results in shared memory between two threads with no locking. In Rust, when you do that, you pass own…
When Go was first announced in 2009, I thought "this is a nice idea, but I really wish it had generics and non-nullable references". Then Rust was announced a few months later, and I thought "wow, this is what Go should have been." However, in the intervening time, Rust has diverged farther from Go. It no longer has green threads nor emphasizes message-passing based concurrency. In addition, Go was ready to use much…
Google has much deeper pockets than Mozilla to build a language and infrastructure.
Re: Fearless concurrency with Rust
#130Earlier quoted context omitted.
Possible M:N.. by default it's 1:1. It's 1 lthread scheduler per actual pthread. static safety guarantees can come with auto pointers (unique_ptr in particular). This is why I said lthread_cpp & C++11.
std::unique_ptr is a significant improvement over prior options, but it can neither ensure correct usage of a mutex (in the sense that it can't cause a data race) nor preserve data race safety for references into another thread's stack. Both of these rely on Rust's ability to limit reference lifetimes, which C++11 doesn't really have (C++14 has an extremely limited form of it in rvalue references, but it's not suffic…
Statically or at runtime guarantees don't buy me much. Regarding mutations, const and copy/move constructors give you want u want. Generally, all you need to do is have 1 thread create an std::unique_ptr object and pass it to the channel for other thread to pick it up.