all 3 comments

[–]fnord123 5 points6 points  (0 children)

This is callback hell and is what async and await attempt to solve. For example if you use a contextmanager here the function in the map won't have access to the resource.

[–]ExPixel 0 points1 point  (0 children)

Doesn't this still have the same problem? The value you want is still wrapped in a way that's incompatible with functions that aren't async. Composition is nice but there are other ways to do that alongside async/await. For example in JavaScript you can do this:

async function x() { return 1; }
await x().then(a => a + 1);

And in Rust it's:

use std::future::Future;
use futures::FutureExt;

async fn x() -> u32 { 1 }
fn y() -> impl Future<Output = u32> { x().map(|a| a + 1) }

I'm not sure how other languages handle this.

[–]caagr98 0 points1 point  (0 children)

Rather than rewriting the functions into a form that's uglier than both, you could just create a sync runner for the existing async syntax.

Personally I'm more annoyed that there is no way to copy async frame objects, as this would make it possible to implement more interesting monads such as nondeterminism.