4 ms·
Despite the title, the article accepts that function colours exist in Rust. The question is, does it matter? Here’s a specific scenario to think about. If I ha
by pansa2 6y ago
Despite the title, the article accepts that function colours exist in Rust. The question is, does it matter?
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“?
- majewsky 6y agoInstead 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()))
- pansa2 6y agoThe 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.
- gpderetta 6y agoexactly this. Unless the language allows abstracting over the async/non-async calls.
- moron4hire 6y agoIn 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);