4 ms·
> Presence of an 'async' decorator on functions isn't strictly needed, but does convey extra information in the API, which is useful. I disagree. It's akin to
by tomp 5y ago
> Presence of an 'async' decorator on functions isn't strictly needed, but does convey extra information in the API, which is useful.
I disagree. It's akin to having a `gc` decorator on a function that uses GC. Maybe useful for C++, but not useful for high-level languages like Java, Swift, Go, JavaScript, Python.
Long-term, I firmly believe `async` will reveal itself to be a mistake. It's simply unwillingness by language designers (or more likely implementors) to treat threading like GC - "that magic is OK, but this magic needs to have extra syntax".
Go chose a different route and treats all runtime magic as implicit behaviour (well, almost all - goroutines can block in loops - but they're trying to fix that, or maybe they have already). Java (project Loom) is going down the same path. It's only a matter of time Swift, Python etc. realize their mistake.
- dcow 5y agoI believe if you read far enough in the thread you’ll see Swift’s “Structured Concurrency” proposal does the same thing. In Go you must `go ...` to invoke concurrency. In Swift that would be `async let = ...` under the proposal (which has already been implemented) on main. `async` just says this function returns a “future” and `await` just desugars the future. I prefer Rust’s approach where the future is an actual type, but there’s a nice element to swift’s where it is prt of the syntax, as is similar with swift’s optionals.
- tomp 5y agoIndeed, async let seems like a massive improvement! (Judging by this proposal [1].) Still the wrong default IMO (should be `let x = async ...` so that you can then do `let xs = [async f(), async g()]`) but definitely a step in the right direction. Now just remove `async` and `throws` function annotations and/or make those default, and all noise will be removed! [1] https://github.com/apple/swift-evolution/blob/main/proposals/0317-async-let.md https://github.com/apple/swift-evolution/blob/main/proposals...
- jlokier 5y ago> unwillingness by language designers (or more likely implementors) to treat threading like GC There is a technical reason behind this, it's not just style. The async-await transformation is highly compatible with calling other things in the C environment and receiving callbacks from that environment. In some implementations the async-await transformation converts nested async functions to stackless state machines that are compatible with the C environment assumed by other libraries (especially in other languages) and by the operating system. But it does have some performance cost, compared with functions that can assume stack scope. That cost only appears when using functions labelled "async". Making every function automatically async in this model is nicer syntax (imho) but adds that cost to every function, unless the compiler is able to do a more global analysis, or deviates from strong compatibility with the C environment. Another approach is to transform them to system threads. Then you don't need the async-await transform and it's compatible with the C environment, but you lose performance in some types of program where async-await is used, and sometimes a lot of memory or address space. So there's still a cost. Especially on targets where threads aren't particularly well implemented. Yet another is green threads or other C-compatible coroutine implementation. This costs some compatibility with the C environment on some targets, though. Switching stacks in C works almost everywhere, but not everywhere, and has portability issues. The standard library function to assist with stack switching has been removed from POSIX, but it was never particularly fast anyway. Go gets around this by being willing to deviate more from the C environment. It goes hand in hand with the very self-contained nature of Go compiled programs. Java gets around this by being a JIT interpreter which is free to do a lot of things its own way inside the Java execution.