I am so happy I have never heard anyone IRL say colored functions. It would annoy me. The concept is interesting but like all engineering it is a trade off. In Node amd Go you don't get a choice anyway. In C# you might choose based on performance thinking of thread pools etc IIRC.
When programming in Node I find in practice async and "colored functions" no issue especially with async await. Except for performance issues they come with sometimes but not at a programming level.
> When programming in Node I find in practice async and "colored functions" no issue especially with async await. Except for performance issues they come with sometimes but not at a programming level.
JS solves this problem in two ways in the ecosystem:
- basically saying "all functions must be async" in practice
- allowing you to await a non-awaitable ("await 3" is valid)
so library authors can "force" async/await, but users don't actually have to interact with it when they don't need to. But "everything" being async/await means it's all 'basically fine' anyways
There's also the fact that JS libraries tend to be "pass in a bunch of callbacks" vs, say, Python's "override this class". It makes it much easier for libraries to have everything be async and have it really not get in the way.
Python libs tend to have much larger API surfaces due to how OOP works. So async-y internals works are harder to isolate cleanly without breaking the public API. But if you make your API "async-first" then the debugging experience in Python is miserable (try pdb'ing your way through awaitables....)
Even here though there are problems. For example, I've tried in the past to replace some lib with a more performant WASM-y thing. But it couldn't be a drop in replacement because the original library was a sync-only API, and the replacement was async!
Something very silly: you write "function add(x, y) { return x+y }". A bunch of people do things like "add(add(x, y), z)" everywhere. You find out you could make "add" "better" with async/await. You now have to get all callers to rewrite.
So what everyone does is just throw _everything_ in to the async/await pile. Which... I guess is fine but I personally dislike writing "await add(await add(x,y)), z)".
(aside: Rust's postfix await at least makes this kinda refactor less annoying)
The Node world was built with asynchronicity in mind. First via callbacks, then Promises, then async/await (Promise-based), so it feels natural now.
But if you take Python (for example), it's a shitshow. You usually have two versions of the same API, split by function name, client, package, or namespace: `foo` and `afoo`, where the a-prefixed one is async and meant to be used inside async function call chains, and the other one is the blocking version for non-async chains (which are still very much in use). It's a pain to develop for, to maintain, to scale, everything.
When programming in Node I find in practice async and "colored functions" no issue especially with async await. Except for performance issues they come with sometimes but not at a programming level.