4 ms·
This is often brought up as if it were a problem, but I see async functions as something similar to IO in Haskell. Almost all asynchronous functions I write are
by brabel 24d ago
This is often brought up as if it were a problem, but I see async functions as something similar to IO in Haskell. Almost all asynchronous functions I write are asynchronous because they will do IO of some sort. Async functions end up being markers of where IO may occur, which is very useful. It is very rare that I need to change a function from being sync to async (and the inverse pretty much never happens), and when that happens it's usually not a big deal (the caller is highly likely to be an async function within a short stack distance, so only one or two functions in the middle normally need to change).
In summary, async is something that looks problematic in theory, but in practice it just works really well!
- mrsmrtss 24d agoAgreed on async. You better know if a function does IO, hiding that can lead to nasty surprises.
- jeremyjh 24d agoThis is only true in Javascript though - even though you have the same function coloring aspect in most other languages with async/await, the other ones do not come with this benefit since synchronous I/O is not only possible but the classical default.
- brabel 24d agoI mostly do this in Dart (though even Dart also has sync IO, it’s just not supposed to be used often), but yeah other languages may not have this benefit.
- hombre_fatal 24d agoJavascript's async-everything is really unique in a domain where async is almost always bolted on to synchronous-everything in some sort of incompatible subecosystem.
- skybrian 23d agoAlso, it’s only true in the browser. Node and Deno have sync I/O. You still end up having to make a choice about whether your function should be async.
- valcron1000 24d agoIf you want to have annotations on IO code you could get it using attributes - and you could even go further by using more precise annotations like `network`, `disk`, etc. The problem with using the type system is that now you need to account for the distinction everywhere (ex. interfaces/traits must support IO-based implementations) only to carry this metadata which should not affect the behavior. In Haskell, IO exists not to track a behavior but to enforce it in a lazy language. In Rust is done due to the lack of a runtime. I recommend reading https://degoes.net/articles/no-effect-tracking https://degoes.net/articles/no-effect-tracking . In summary, most languages could do with the Go/Java virtual thread async model dropping async/await entirely.
- skrtskrt 22d agoDon’t you need a runtime to do Go/Java style?