4 ms·
Alice ML¹ had that in 2000², and the idea of promises/futures dates back to the 70s. async/await to flatten promise hierarchies is decidedly _not_ a new idea.
by PeCaN 10y ago
Alice ML¹ had that in 2000², and the idea of promises/futures dates back to the 70s. async/await to flatten promise hierarchies is decidedly _not_ a new idea.
¹ http://www.ps.uni-saarland.de/alice/manual/futures.html http://www.ps.uni-saarland.de/alice/manual/futures.html
² Well, it used "spawn" instead of "await". The semantics are very similar though.
- soulbadguy 10y agothe semantic and working implementation of spawn/away are quite different from async/await. While they might be related, i think it's kinda of stretch to call them prior arts...
- PeCaN 10y agoThey're really not all that different. Both are implementations of concurrency based on data-flow synchronization. Alice ML is explicit about running concurrent promises (it has other types of promises as well) in “threads”, but they're lightweight userspace threads. C# AFAIK doesn't specify any particular execution model for await.
- Const-me 10y agoThe innovation was to combine async/await to flatten promise hierarchies with asynchronous callback-based IO under the hood to implement those promises without using background threads. That was the new idea that suddenly made those decades-old promises useful for the software industry, as it allowed both blocking-style code simplicity and callbacks-style IO scalability. The ML link says “evaluates the expression exp in a new thread and returns immediately with a future of its result” which translates to “not scalable”.
- PeCaN 10y agoAlice ML “threads” are more like Erlang threads than C# threads. They're lightweight userspace threads and you can have thousands of them. That's quite scalable. Also, that's not a new idea. Blocking-style code with async I/O scaling was pioneered by Oz in 1991. (It did it a little bit differently from Alice ML.)
- Const-me 10y ago“They're lightweight userspace threads and you can have thousands of them.” — can I use 1000 lightweight userspace threads to run 1000 concurrent kernel-space IO operations on files or sockets, one thread each?
- PeCaN 10y agoYes, that's precisely the point.
- Const-me 10y agoMS implemented IOCP in Windows NT in 1994, then BSD implemented kqueue in 2000, then Linux implemented epoll in 2002 (they all functionally very similar). That means outside Windows, asynchronous event-based IO was only possible after 2002 (that’s when the first version of libevent was released). And yet you’re telling me the ML threads in 2000 were capable of high-performance async IO? You sure about that? In 2000, which kernel API you think that runtime used for IO?
- PeCaN 10y agoYes, and VMS had asynchronous system traps for I/O in 1977.² ³ And yes, of course? Erlang could do scalable async I/O in 1988. Alice ML and Erlang both emulate async I/O by having a few OS level threads each switching between a large number of userspace/VM threads. They queue I/O operations then preempt VM threads when results are ready. For a while that was the only sane way around the clusterfuck that is async I/O on *nix. It still scales fine and I think there's rather little interest in converting either Alice ML or Erlang to libevent/libev/libuv. ¹ The initial Erlang VM was very slow, but the I/O model was there. BEAM was created in 1992 and was fast enough for Ericsson to use in production. ² NT and VMS were both designed by David Cutler, who is more or less the father of asynchronous I/O at the OS level. ³ Incidentally, if you think async I/O in 1977 was advanced, you should look at AS/400 or VOS sometime.
- 10y ago