4 ms·
And that's a great achievement! If there were a Nobel prize for practical use of a type system, the Rust team would get it. But overselling it ("Rust goes out
by acconsta 11y ago
And that's a great achievement! If there were a Nobel prize for practical use of a type system, the Rust team would get it.
But overselling it ("Rust goes out of its way to make it easy and safe to write multithreaded code" except oh yeah it can deadlock at any time) is a mistake.
- kibwen 11y agoYou act as though deadlocks in Rust are trivial and pervasive, but they aren't. It just makes no guarantees that deadlocks will not occur. Show me a language that statically prevents deadlocks and I'll be quite curious to check it out. In any case, writing concurrent code in Rust is safe and easy. I suggest you try it. :)
- acconsta 11y ago>You act as though deadlocks in Rust are trivial and pervasive, but they aren't Writing nontrivial multithreaded code using thread and mutex primitives is very hard to get right (not only due to data races, but also race conditions and deadlocks). Has your experience been different? >Show me a language that statically prevents deadlocks OK, idiomatic Go and Erlang will never deadlock. Sure, you can use mutexes in Go, but unlike in Rust they aren't the only means of achieving high levels of concurrency (in fact, they are explicitly discouraged). I find this attitude from the Rust community disheartening. Not everything needs to be statically verified to be useful.
- dbaupp 11y agoBoth of those languages will semantically deadlock: forget to send a message on a channel and a different thread will sit there waiting forever. It's not a mutex-deadlock, but it achieves the same thing. Neither of those languages protects against this. (And Rust has exactly that level of "deadlock" freedom: it has channels too.) In any case, you seem to be ignoring what everyone is saying: Rust doesn't guarantee deadlock freedom, but it still tries to help. Mutexes can be an important building for some things, but they're not the final story. There's atomics and channels in the standard library right now, and now that 1.0 is released, there'll be a growth of even better abstractions. One of the people working full time on Rust has a PhD in concurrent programming, and has it as a personal goal to make Rust great at it. You can see his initial work on his blog[1], and read his thesis which introduces "reagents" (something he has expressed interest in implementing in Rust)[2]. 1.0 is the start for Rust, not the end. [1]: http://aturon.github.io/blog/2015/08/27/epoch/ http://aturon.github.io/blog/2015/08/27/epoch/ [2]: https://www.mpi-sws.org/~turon/turon-thesis.pdf https://www.mpi-sws.org/~turon/turon-thesis.pdf
- acconsta 11y agoPutting the word "semantically" in front of deadlock doesn't change its meaning: https://en.wikipedia.org/wiki/Deadlock https://en.wikipedia.org/wiki/Deadlock Either way, redefining the word does nothing to make mutexes and native threads safer or easier to use in practice. I can't emphasize this enough — data races are not the only kind of concurrent programming error, yet they are the only kind prevented by borrow checking. Go, Erlang, and Node have high level approaches to concurrency that reduce other categories of errors (in addition to providing massive performance benefits vs. naive native threading). I think the time to add good concurrency abstractions to a language is before 1.0, but I'm in strong disagreement with the community there. And judging by this thread, concurrent IO isn't even on the core team's roadmap. This is not a good sign for a language that sells itself on concurrency! Look at the situation 10 months ago. How much has it improved? https://www.reddit.com/r/rust/comments/2l0a4b/do_rust_web_servers_use_libuv_through_libgreen_or/ https://www.reddit.com/r/rust/comments/2l0a4b/do_rust_web_se... Channels are a step in the right direction, but are pretty limited without coroutines (channels without coroutines are just synchronized queues). Atomics are cool, but they address a totally different problem. Reagents, well, let's see an implementation. C++ has needed a successor for many years now, and Rust is the best candidate. But lofty claims notwithstanding, the Rust concurrency situation is pretty dreadful.
- dbaupp 11y ago> Putting the word "semantically" in front of deadlock doesn't change its meaning: And focusing on hangs in concurrent programs that are caused by using a data structure called "mutex" doesn't stop one getting exactly the same symptoms via your apparently-perfect channels. One can use channels to get all four of the conditions required for a deadlock, especially Go's synchronous-by-default channels. Any time you have a protocol of multiple tasks communicating with each other in some structured way, it's possible to break that protocol and hence have tasks sitting around waiting for messages that aren't coming. Especially in languages like Go/JavaScript/... which aren't powerful enough to model things like session types in their type system, e.g. https://www.reddit.com/r/rust/comments/3jhd56/session_types_safe_internal_communication/ https://www.reddit.com/r/rust/comments/3jhd56/session_types_... > I can't emphasize this enough — data races are not the only kind of concurrent programming error, yet they are the only kind prevented by borrow checking Yes, that's exactly why the whole Rust community tries to be very careful about using "data race" when talking about concurrency in Rust. However, it is the case that data races are the worst sort of concurrency bug: they are undefined behaviour and so can lead to arbitrary memory corruption, possibly only appearing a long way from the actual place with UB. Deadlocks and other problems are, by default, much more controlled in their failure modes. Rust focuses on truly outlawing large classes of horrible problems: dangling pointers, iterator invalidation, data races (and all without requiring a garbage collector, although a GC barely helps with the latter two). It also tries to help with other problems with fewer guarantees, but even just being memory safe is a huge step up from widely used low-level languages (i.e. C/C++). All the languages you mention are quite opinionated in their concurrency, imposing costs that Rust doesn't and can't, for its target space. (And, Go certainly doesn't provide any guarantees at all, not even data race freedom.) > in addition to providing massive performance benefits vs. naive native threading Important qualification: for IO bound tasks. Which is perfectly fine, but it needs to be understood. > I think the time to add good concurrency abstractions to a language is before 1.0, but I'm in strong disagreement with the community there What's so important about being pre-1.0? You seem focused on it, but I don't understand why. What benefit does Rust gain by delaying the release of 1.0 for months/years just to get good async IO support? Why is this particular pet feature any more important than everyone else's pet feature? (There have been so many requests: "why couldn't X make it into 1.0?") If you're concerned about theoretical fragmentation of the ecosystem... that's not a problem in practice: mio is the standard. > And judging by this thread, concurrent IO isn't even on the core team's roadmap Wrong, it's very much on the roadmap, e.g. Alex Crichton (core team member) has been adding windows support to mio himself. > Look at the situation 10 months ago. How much has it improved? A lot. There's a burgeoning ecosystem built around mio. --- In any case, Rust has been stable for barely 3 months. Be patient, and give it time for the concurrency story to blossom from the seeds that have been sown so far. Based on the experience so far, I'm pretty confident that Rust can easily be much better (i.e. more performant and reliable) than both Node and Go and even Erlang. (Of course, it may be syntactically less nice, since those languages bake it in deeply, while Rust is less opinionated.)
- kibwen 11y agoYou really must not have done much concurrent programming if you think Go and Erlang won't deadlock. :P Throwing the "idiomatic" qualifier on there isn't a defense; "idiomatic Rust" doesn't deadlock either.
- acconsta 11y agoLet me be more precise then. Goroutines enable a fan out pattern in which each task, even small ones, is a separate asynchronous routine. Tasks fan out from a coordinator routine and their results fan back in: https://talks.golang.org/2012/concurrency.slide#46 https://talks.golang.org/2012/concurrency.slide#46 This is great for a couple reasons: It's automatically concurrent without explicit pooling and locking. The code flow remains sequential. No callback hell! It reduces concurrency errors. The locking pattern is naturally acyclic! Nothing races! Ah, but Go has a big runtime, you say! We can't have that in Rust! Well, here's the same thing in C and in C++: http://libmill.org/tutorial.html http://libmill.org/tutorial.html http://www.boost.org/doc/libs/1_59_0/libs/coroutine2/doc/html/coroutine2/motivation.html http://www.boost.org/doc/libs/1_59_0/libs/coroutine2/doc/htm... Coroutines are a wonderful tool for building concurrent applications, and I dearly hope we get them in Rust.
- Manishearth 11y agoForget to update that 3 after fiddling with the channels? Deadlock. Forget to unlock a mutex when dealing with shared data? Deadlock (and Go doesn't have RAII mutexes, so it's very easy to do this). The pattern you put forth is possible in Rust too. Use mio if you want goroutine-like efficiency. Nothing new.
- acconsta 11y ago>Forget to update that 3 after fiddling with the channels? Deadlock To be fair, how long would that take to debug? >Forget to unlock a mutex when dealing with shared data? You'll note there are no mutexes. RAII mutexes are great (although less useful without exceptions). But the entire point of Go's concurrency model ("share by communicating") is that you don't need need to deal with them. >Use mio if you want goroutine-like efficiency For a personal project, I would. But will any commercial entity use an unstable, unportable library with a single maintainer for critical functionality in their app? Because that's the concurrent IO situation in Rust, now and for the foreseeable future.
- deleted 11y ago[deleted]