This is exciting. It allows programmers to model their problems in code that fully accounts for the parallelism. For comparison, here is async/await in Zig: https://ziglang.org/documentation/master/#Coroutines Zig decided to go the other way - when you async call a function, it does eagerly evaluate until the first suspend point. This is less overhead than immediately suspending, plus it removes the dependency of the…
It's exciting to see so many systems programming languages implement async/await. For a further comparison, Nim works in the same way as Zig when it comes to eager evaluation. Something that I'm particularly proud of when it comes to Nim's async/await implementation is that everything, right down to the macro which defines what `await` means, is implemented in the standard library. The compiler only implements the co…
Async and Await in Rust: a full proposal
121–130 of 196 posts
Re: Async and Await in Rust: a full proposal
#122And 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…
I don't have time to write a whole essay, so let me just establish my credentials: - I wrote the generic associated types RFC (how Rust will implement higher kinded polymorphism). - I wrote the const generics RFC (the closest Rust will get to dependent types). - I wrote the async/await RFC, as well as the linked blog post. That is to say that I am intimately familiar with how Rust's type system can be extended to sup…
Re: Async and Await in Rust: a full proposal
#123Earlier quoted context omitted.
> 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 quite dislike the current async trend, so you do not have to sell me the alternatives. I was just describing the status quo. 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…
The point is that only at the very top of the call stack or the very bottom should you ever need to care or think about whether code is async, because 99% of the time (every bit of code between main and syscalls... which is almost all of it) that's the only place you should need to care. This can be completely automatic because the compiler already knows where to insert await/async, it only needs to know when to use async (decided by main) and what to call at the end (decided by the syscall funcs).
Re: Async and Await in Rust: a full proposal
#124I'm somewhat disappointed that rust is going with async style stackless continuations. I'm a huge fan of stackfull coroutines/continuations as they are much more elegant and flexible. The downside is that they need a full stack, but I strongly believe (but can't prove) that rust has enough annotations and lifetime capabilities that it should be able to guarantee single frame allocation (or even no allocation for full…
You emphasize that stackfull coroutines could get down to a single allocation, but I'm not sure exactly what you mean. I could trivially get a stackfull coroutine down to a single allocation, the same way that systems thread do it: by allocating a defined stack size and raising a seg fault when you go over it. The trick that "stackless coroutines" can achieve, and do achieve in Rust, is not just getting a single allo…
Interestingly this is similar to the analysis required to completely optimize a way the coroutine stack frame allocation. And because rust type system is good at tracking lifetimes and nested scopes, I think it might be possible to extend it ti guarantee this sort of optimization. Unfortunately this way beyond my pay grade.
Re: Async and Await in Rust: a full proposal
#125And 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…
I don't have time to write a whole essay, so let me just establish my credentials: - I wrote the generic associated types RFC (how Rust will implement higher kinded polymorphism). - I wrote the const generics RFC (the closest Rust will get to dependent types). - I wrote the async/await RFC, as well as the linked blog post. That is to say that I am intimately familiar with how Rust's type system can be extended to sup…
Sorry, but I don't buy it. I had a half-baked, unfinished proposal for an effects system that would have allowed Rust to implement async/await just as efficiently (no stackful coroutines) along with any number of other effects [0]. Maybe it wouldn't have been a good idea due to stretching Rust's complexity budget too far, but that's very different from saying it's impossible. Having watched the development of Rust closely I really think that the design team just didn't understand the theory side well enough to be able explore the design space here. (I'm not being as critical as I might sound, PL theory is hard and the Rust devs have wielded it much more competently than the designers of any other non-research language).
[0] https://internals.rust-lang.org/t/start-of-an-effects-system...
Re: Async and Await in Rust: a full proposal
#126Earlier quoted context omitted.
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?
Sure there is: take an undelimited continuation API, and restrict the resulting continuations to be called only once. Most use cases still work just fine, and I think it would be strange to call that anything other than "undelimited one-shot continuations". Maybe what you have in mind, though, is the traditional argument, that there's no such thing as undelimited continuations. All continuations are naturally "delimi…
Re: Async and Await in Rust: a full proposal
#127And 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…
I don't have time to write a whole essay, so let me just establish my credentials: - I wrote the generic associated types RFC (how Rust will implement higher kinded polymorphism). - I wrote the const generics RFC (the closest Rust will get to dependent types). - I wrote the async/await RFC, as well as the linked blog post. That is to say that I am intimately familiar with how Rust's type system can be extended to sup…
This is probably only because you didn't develop the answer fully but i still struggle to see how monads (or other structures in that family) couldn't apply here: they aren't implemented in any way and just provide interface (eg not caring about rust at all, the semantic of that feature here is very monadic, it should mostly behave like the CPS monad). Anyway, i'm gonna stop arguing, look at how it is/will be implemented and hopefully wait for that essay of yours, to have a broader picture.
Re: Async and Await in Rust: a full proposal
#128Earlier quoted context omitted.
Sure there is: take an undelimited continuation API, and restrict the resulting continuations to be called only once. Most use cases still work just fine, and I think it would be strange to call that anything other than "undelimited one-shot continuations". Maybe what you have in mind, though, is the traditional argument, that there's no such thing as undelimited continuations. All continuations are naturally "delimi…
I guess that's what I have in mind. Any practical coroutine API has an explicit coroutine creation and yielding point that act as continuation delimiters.
Re: Async and Await in Rust: a full proposal
#129Earlier quoted context omitted.
I don't have time to write a whole essay, so let me just establish my credentials: - I wrote the generic associated types RFC (how Rust will implement higher kinded polymorphism). - I wrote the const generics RFC (the closest Rust will get to dependent types). - I wrote the async/await RFC, as well as the linked blog post. That is to say that I am intimately familiar with how Rust's type system can be extended to sup…
> Monads as implemented in pure functional programming languages like Haskell cannot usefully abstract over asynchronous and synchronous IO in Rust for a variety of reasons having to do with the way the type system exposes low level details by virtue of Rust being a systems programming language. I do not believe that `do` notation could be a useful mechanism for achieving either the ergonomics or the performance that…
Sticking to the first part: an effect system is not what the user I was responded to was talking about. They were talking about building do notation on top of type classes with higher kinded polymorphism, which cannot effectively abstract over the monadic operations in Rust.
Re: Async and Await in Rust: a full proposal
#130Earlier quoted context omitted.
I don't have time to write a whole essay, so let me just establish my credentials: - I wrote the generic associated types RFC (how Rust will implement higher kinded polymorphism). - I wrote the const generics RFC (the closest Rust will get to dependent types). - I wrote the async/await RFC, as well as the linked blog post. That is to say that I am intimately familiar with how Rust's type system can be extended to sup…
Didn't mean to bash the lang design team at all, actually i was kinda hoping for you folks to reply interesting and tricky stuff about how things are not so simple. This is probably only because you didn't develop the answer fully but i still struggle to see how monads (or other structures in that family) couldn't apply here: they aren't implemented in any way and just provide interface (eg not caring about rust at a…
Higher kinded polymorphism results in trivially undecidable type inferences without something like currying; the restrictions needed to support it would be arbitrary and weird given that Rust does not have currying (essentially some rules to reconstruct the restrictions of currying in type operator context).
Instances of both Future and Iterator do not implement the Monad type class as defined in Haskell, because the "fmap" operator does not return the "self" type parameterized by a new type, it returns it own new type. This is because the state machine they represent is leaked through their function signature.
Do notation doesn't work with the imperative control flow that Rust has, which other people have already discussed.