From a02190547f16286ae5a4fefa1f7e89a12675ff24 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Thu, 28 Mar 2024 19:17:44 +0000 Subject: [PATCH] Add Rust example to prior art Using the no-op `Waker`, we can express generators and coroutines in Rust. Let's close our list of prior art examples with that. --- text/3513-gen-blocks.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/text/3513-gen-blocks.md b/text/3513-gen-blocks.md index 2defa4a0..bfff8676 100644 --- a/text/3513-gen-blocks.md +++ b/text/3513-gen-blocks.md @@ -582,6 +582,31 @@ Note that there is no library being used here and that `yield` is not a keyword [koka]: https://koka-lang.github.io/ +## Rust + +In Rust, `async` blocks are built on top of the coroutine transformation. Using a no-op `Waker`, it's possible to expose this transformation. With that, we can build generators. Without the assistance of macros, the result looks like this: + +```rust +let odd_dup = |xs| { + Gen::new(async move |mut y| { + for x in xs { + if x % 2 == 1 { + y.r#yield(x * 2).await; + } + } + }) +}; + +let odd_dup = pin!(odd_dup(1u8..20)); +let odd_dup = odd_dup.init(); + +for (i, x) in odd_dup.enumerate() { + assert_eq!((i as u8 * 2 + 1) * 2, x); +} +``` + +Crates such as [`genawaiter`][] use this technique. + # Unresolved questions [unresolved-questions]: #unresolved-questions