wesselbindt 15 minutes ago

I've always found the criticism leveled by the colored functions blog post a bit contrived. Yes, when you replace the words async/await with meaningless concepts I do not care about such as color, it's very annoying to have to arbitrarily mark a function as blue or red. But when you're honest with yourself and interpret the word "async" as "expensive", or as "does network calls", it becomes clear that "async/await" makes important features of your function explicit, rather than implicit. Seeing "await" gives me more information about the function, without having to read the body of the function (and the ones it calls, and the ones they call, etc). That's a good thing.

There are serious drawbacks to async/await, and the red/blue blog post manages to list none of them.

I've wrote a blog in response to OP containing a more detailed version of the above:

https://wpbindt.github.io/async/opinions/programming/2024/01...

omgbear an hour ago

I've thought about this a lot in relation to typescript over the years and had various opinions -- For some time I thought it'd be better if there was an implicit `await` on every line and require `void` or some other keyword to break execution like `go` in Golang.

But, eventually I realized the difference in pre-emption between languages -- Go can (now) preempt your code in many places, so locks and thread-safety are very important.

The javascript runtime only preempts at certain places, `await` being one. This means I can know no other code can be running without explicit locks around all critical sections.

Finally understanding the trade-offs, I no longer am as frustrated when recoloring a bunch of functions. Instead, I can appreciate the areas where I'm not required to lock certain operations that I would in other languages.

Rapzid an hour ago

I still haven't seen a good "solution" to this "problem" for imperative style programming. Why the quotes? Because the functions have different signatures, thus different functions(colors).

And IT MATTERS. That's why you have structured concurrency hot on the heels of Loom. And once you are using structured concurrency constructs... Ehh, it's not the magic "solution" we were sold anymore is it?

  • HiJon89 36 minutes ago

    Not sure I follow. The function coloring problem is still solved in that scenario. You can apply structured concurrency to any function (there’s no colors), and any function can contain structured concurrency within it (ie, using structured concurrency doesn’t color your function)

  • immibis an hour ago

    The article is not about functions having different type signatures but being somehow fundamentally different. It occurs every time we try to qualify and enforce restrictions on functions, whether it's async, pure, nonblocking, or whatever. Although they aren't all harder to call, they always cause problems with higher order functions. An idea of "effect generics" tries to improve upon this - you write something like

    template<effect T> T_function List filter(List list, T_function pred)

    (element type committed for brevity) and then filter is async if the predicate is async, etc - it's pure if the predicate is, nonblocking if the predicate is. If you continue in this direction, your language gets more complex than C++. The other options are to just accept that you need a separate filter function for async and non async predicates, or to do away with function flags (doesn't work for CPS style async of course).

    • Rapzid 18 minutes ago

      This article is about exactly what I'm addressing. I stopped reading after your false premise.

immibis an hour ago

There is also coloured data: stack vs heap, threadsafe vs not, disk vs memory vs SQL, mutable vs immutable, etc ...

Another comment: Python's async/await is precisely syntactic sugar for generators. It just changes the keywords and checks that you only use await in a function labeled async.

Edit: my rate limit appears to have been increased.