3 ms·
TFA is pretty good. I would shrink it to: If you're a language/platform like Swift or Rust (see also Erlang or OCaml) you're gonna end up with some kind of use
by camgunz 3y ago
TFA is pretty good. I would shrink it to:
If you're a language/platform like Swift or Rust (see also Erlang or OCaml) you're gonna end up with some kind of userspace task scheduler because OSes don't give you enough control over threads. If you're a systems language you're gonna use stackless coroutines because speed/memory and C interop. In Rust, you use their task scheduler via async/await, but sadly the ergonomics aren't wonderful and there's now weirdo problems like what reactor/engine/whatever they standardize on etc. The interesting and good stuff will be built on top of async/await, probably shouldn't have touted it as the interface.
My hypothesis here is that something like concurrency/parallelism exists on two levels. You've gotta get the underlying implementation right, and you have to expose a mental model and affordances for using it. The problem is that languages that are good at the first thing are usually real bad at the second thing. More broadly I think this is a trilemma--pick any 2 for your language:
- small
- can implement performant concurrency/parallelism
- can express a high-level mental model of concurrency/parallelism
No one should be surprised that Rust will throw "small" overboard here. I think the only question is how many models will they support? Will they do CSP AND actors (they're different!)? Will there be some kind of OpenMP type thing? Will there be new keywords or--shudder--new SYNTAX?
---
I feel like I have to say Go's solution to this is bold and elegant. Giving up straightforward C interop was pretty gutsy, and the affordances for working with its task scheduling system are familiar and intuitive. I want to stress this (because TFA goes way out of its way to be a little shitty w/ Go): this worked absolutely great. Tons of good software is written in Go. It is super effective. It spent its innovation tokens on experience and tooling and that was really successful (i.e. type systems aren't the only way to fight data races). There were exactly zero debates about stuff like await syntax or what engine to use/standardize. In the time it took Rust to ship async/await, probably 7 billion actually useful Go programs were shipped. Just because someone else's values aren't yours doesn't mean they're the wrong values. I think it's cool that people like Boats are being really thoughtful about how to do this and sharing their thoughts and processes out in the open. I just think there's room in this crazy world for at least two points of view, and that we could do with a little less sneering.
- zozbot234 3y ago> Will they do CSP AND actors (they're different!)? Will there be some kind of OpenMP type thing? Rust builds support for all of these models based on it's basic underlying "shared ^ mutable" and "Send/Sync" safety guarantees. It should be quite clear based on this whether you're sharing access to some read-only data, staying within a single-threaded context with mutability, or relying on some sort of synchronization primitive (be it atomic data, locks, r/w mutexes etc). The fact that we understand some uses of these facilities as involving patterns such as "CSP" or "Actors" is quite beside the point.
- camgunz 3y agoI don't super understand your point. I understood TFA to making the argument that dealing with the low-level business of stuff like mutexes and async/await isn't what most people want to do: > We should aspire not to simplify the system by hiding the differences between futures and threads, but instead to find the right set of APIs and language features that build on the affordances of futures to make more kinds of engineering achievable than before. The stuff you listed, along with async/await, makes this possible. Isn't that what TFA is saying?