Skip to content

Commit a021905

Browse files
committed
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.
1 parent 7eacd06 commit a021905

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

text/3513-gen-blocks.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,31 @@ Note that there is no library being used here and that `yield` is not a keyword
582582

583583
[koka]: https://koka-lang.github.io/
584584

585+
## Rust
586+
587+
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:
588+
589+
```rust
590+
let odd_dup = |xs| {
591+
Gen::new(async move |mut y| {
592+
for x in xs {
593+
if x % 2 == 1 {
594+
y.r#yield(x * 2).await;
595+
}
596+
}
597+
})
598+
};
599+
600+
let odd_dup = pin!(odd_dup(1u8..20));
601+
let odd_dup = odd_dup.init();
602+
603+
for (i, x) in odd_dup.enumerate() {
604+
assert_eq!((i as u8 * 2 + 1) * 2, x);
605+
}
606+
```
607+
608+
Crates such as [`genawaiter`][] use this technique.
609+
585610
# Unresolved questions
586611
[unresolved-questions]: #unresolved-questions
587612

0 commit comments

Comments
 (0)