Now that Rust is getting some maturity i worry that it gets too complex in too much direction just because it's not powerful enough to express the few common abstraction, of which several instances are being added as distinct concepts (async&try, const datakind, higher-order poly--especially for lifetimes, named impls, before-after memory state for references...).
Async and Await in Rust: a full proposal
101–110 of 196 posts
Re: Async and Await in Rust: a full proposal
#102Earlier quoted context omitted.
Undelimited continuations are memory sieves. Delimited continuations are better but a bit less useful.
Genuine question: aren't all one shot continuations (like the ones this thread is about) naturally delimited? Is there even such a thing as an undelimited one shot continuation?
Re: Async and Await in Rust: a full proposal
#103Earlier quoted context omitted.
I think it should be possible to design an async system that is generically async , i.e. whether a given function with no special annotations or syntax is async (including all of the async-able calls that function makes transitively) is entirely determined by the top-level caller at compile time . The called function doesn't need any special syntax, and in fact doesn't even need to consider being async at all: the as…
To allow for separate compilation you need to compile each function twice though: a CPS version and 'classic' one. This can be wasteful. You also need annotations in the object file to describe the frame size of each CPS function. At some point this was seriously considered for C++ and I'm sure some language implementations actually do it. Or you go with cactus stacks which have their own set of issues.
More wasteful than writing each function twice? See C# for endless examples of libraries that have manual duplicate X() and XAsync() for every single method. If you compare the two they're almost always have the exact same body, except the async version has "async" and "await" peppered in and calls duplicate XAsync methods (which are implemented the same, except they call XAsync methods... you might be seeing a pattern here).
If I'm not mistaken most rust doesn't use separate compilation and is built from source. In this case the compiler can treat it just like normal generics and just not compile it until it's used. And even with separate compilation for, e.g. a library, a very basic LTO would trivially trim out the unused methods when compiled into a final binary. And if you don't want 2x library itself, even then you can just use an escape hatch to turn it of on the crate/impl/function level and it's still better for you than the status-quo where you have to manually add a bunch of tokens and junk that the compiler already knows how to do precisely.
If anything is wasted it's human effort because we're wasting our time doing something the computer can do better and faster.
> "annotations in the object file to describe the frame size"
Wouldn't you need this anyway for anything async, even if it's manual? This seems like an argument against async in general, not automatic async.
Re: Async and Await in Rust: a full proposal
#104And yet we somehow don't acknowledge the fact that this is just do-notation for some specific monad--yeah, that powerful abstraction that can't be expressed in Rust because we don't allow higher-order polymorphism. Don't get me wrong, i'm bitter because i feel like Rust really is almost in the right direction for the future of language design. Yet there is a long time before we get a language with a really precise ty…
(Previous version of this comment said "HKT" but that's not purely right; we have a path forward for something at least HKT-like, but do notation is the bigger question.)
Re: Async and Await in Rust: a full proposal
#105And yet we somehow don't acknowledge the fact that this is just do-notation for some specific monad--yeah, that powerful abstraction that can't be expressed in Rust because we don't allow higher-order polymorphism. Don't get me wrong, i'm bitter because i feel like Rust really is almost in the right direction for the future of language design. Yet there is a long time before we get a language with a really precise ty…
Supporting do notation or not isn’t some sort of position we’re taking as a language; it’s an open research problem if do notation can work in Rust. Until that’s solved at all, we’re just not sure it’s possible. (Previous version of this comment said "HKT" but that's not purely right; we have a path forward for something at least HKT-like, but do notation is the bigger question.)
Like what is the real road-blocker, since we're talking here about abstractions that are gonna be monomorphised (at most into lifetime-polymorphic function, which anyway get erased) and known statically, right? Is it only a problem of getting the typing rules consistent and robust?
Re: Async and Await in Rust: a full proposal
#106Earlier quoted context omitted.
Supporting do notation or not isn’t some sort of position we’re taking as a language; it’s an open research problem if do notation can work in Rust. Until that’s solved at all, we’re just not sure it’s possible. (Previous version of this comment said "HKT" but that's not purely right; we have a path forward for something at least HKT-like, but do notation is the bigger question.)
Yeah, sure, i understand that, hn comments just need to be a bit spicy (btw, any ref of papers or other stuff in that area? i didn't follow closely but didn't see too much moving, actually i don't even know what the big question marks are). Although i really believe it's not about if but how, so let's hope that when the time comes Rust will be able to take the tough changes necessary to unify the different branches t…
First off, do notation desugars to closures. But Rust has three different kinds of closures. How does that work?
Furthermore, Rust has imperative control structures. How does all of this interact with each other? Are you now no longer allowed to use those constructs inside of do notation? That feels inconsistent.
I don't know of any languages that have something like do notation but don't have everything boxed. It makes everything easier, but that's not generally acceptable in Rust. For example, we can use async/await with no dynamic allocation. Could we with do notation?
"Open question" doesn't mean "impossible", mind you. But nobody has ever come up with a design. In the meantime, we have users to support...
Re: Async and Await in Rust: a full proposal
#107Earlier quoted context omitted.
To allow for separate compilation you need to compile each function twice though: a CPS version and 'classic' one. This can be wasteful. You also need annotations in the object file to describe the frame size of each CPS function. At some point this was seriously considered for C++ and I'm sure some language implementations actually do it. Or you go with cactus stacks which have their own set of issues.
> you need to compile each function twice ... This can be wasteful. More wasteful than writing each function twice ? See C# for endless examples of libraries that have manual duplicate X() and XAsync() for every single method. If you compare the two they're almost always have the exact same body, except the async version has "async" and "await" peppered in and calls duplicate XAsync methods (which are implemented the…
I think that a good compromise would be implicitly inferring the 'async-ness' of template functions instantiation (or whatever they are called in your language of choice) based on a magic continuation parameter, which would also go around the separate compilation issue (assuming the language does generic monomorphization).
Re: Async and Await in Rust: a full proposal
#108Earlier quoted context omitted.
To allow for separate compilation you need to compile each function twice though: a CPS version and 'classic' one. This can be wasteful. You also need annotations in the object file to describe the frame size of each CPS function. At some point this was seriously considered for C++ and I'm sure some language implementations actually do it. Or you go with cactus stacks which have their own set of issues.
> you need to compile each function twice ... This can be wasteful. More wasteful than writing each function twice ? See C# for endless examples of libraries that have manual duplicate X() and XAsync() for every single method. If you compare the two they're almost always have the exact same body, except the async version has "async" and "await" peppered in and calls duplicate XAsync methods (which are implemented the…
If I have a sync function and I call something async, I should be able to just .wait() it, I think, and get the sync behavior.
Re: Async and Await in Rust: a full proposal
#109Earlier quoted context omitted.
Supporting do notation or not isn’t some sort of position we’re taking as a language; it’s an open research problem if do notation can work in Rust. Until that’s solved at all, we’re just not sure it’s possible. (Previous version of this comment said "HKT" but that's not purely right; we have a path forward for something at least HKT-like, but do notation is the bigger question.)
Yeah, sure, i understand that, hn comments just need to be a bit spicy (btw, any ref of papers or other stuff in that area? i didn't follow closely but didn't see too much moving, actually i don't even know what the big question marks are). Although i really believe it's not about if but how, so let's hope that when the time comes Rust will be able to take the tough changes necessary to unify the different branches t…
Re: Async and Await in Rust: a full proposal
#110Earlier quoted context omitted.
Yeah, sure, i understand that, hn comments just need to be a bit spicy (btw, any ref of papers or other stuff in that area? i didn't follow closely but didn't see too much moving, actually i don't even know what the big question marks are). Although i really believe it's not about if but how, so let's hope that when the time comes Rust will be able to take the tough changes necessary to unify the different branches t…
There's multiple issues. The biggest ones that I can recall, off the top of my head: First off, do notation desugars to closures. But Rust has three different kinds of closures. How does that work? Furthermore, Rust has imperative control structures. How does all of this interact with each other? Are you now no longer allowed to use those constructs inside of do notation? That feels inconsistent. I don't know of any…