Re:Rust’s async isn’t colored
by moron4hire on Thursday March 11, 2021 @10:58AM
(#26425394)
In JavaScript, you can await a non-promise returning function and it's a NO-OP. So if you are taking a function as a parameter, you can await it safely, regardless of whether it's async or not.
function giveMe3() { return 3; }
function giveMe3Async() { return Promise.resolve(3); }
async function logger(func) { return console.log(await func()); }
await logger(giveMe3);
await logger(giveMe3Async);Instead of
f2(g(h2()))
you'd write something like f2(async { g(h2().await) }).await
if f2 takes a future, or f2(g(h2().await)).await
if it takes a value. (The latter is more common.) The equivalent in JS would be await f2(g(await h2()))The example uses `g(h2)`, not `g(h2())` - `g` takes the function `h2` as an argument, and the call(s) to `h2` are made from within `g` itself.
If calling `h2` requires an `await` if and only if `h2` is async, then the function `g` can’t be used for both the synchronous and async cases. AFAIK this is the main objection to having two function colours.
Here’s a specific scenario to think about. If I have synchronous functions `f`, `g` and `h`, `f` can call `g(h)` and `g` can in turn call its parameter `h` - no problems. Now if I have async functions `f2` and `h2`, can `f2` call `g(h2)` without the need to write an async version of `g`?
In a language like Lua (with stackful coroutines), the answer is “yes” - `g` can be called from and can call functions of either colour. But AFAIK in JavaScript (with callbacks, promises and async/await based on promises), and in Python (with async/await based on stackless coroutines), the answer is “no” - the colour of `g` must match that of its caller and callee.
What’s the answer for Rust? Can we answer “yes” by following this article’s recommendations of “spawn [g] as a blocking task” and “throw [h2] on an executor“?