Skip to content

Commit

Permalink
Update quizzes
Browse files Browse the repository at this point in the history
  • Loading branch information
willcrichton committed Sep 26, 2024
1 parent 388e1a3 commit 3a2eb34
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 107 deletions.
86 changes: 61 additions & 25 deletions quizzes/async-03-more-futures.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,48 +27,84 @@ id = "68680e2e-7a9f-4cee-8080-70e57fe5a2b3"
[[questions]]
type = "MultipleChoice"
prompt.prompt = """
Imagine Rust did not require that futures were pinned in order to be polled.
Which of the following async functions could potentially cause undefined behavior if not pinned?
Say you are designing a utility function with the following specification:
> `map_stringify` takes two arguments: a vector of inputs, and an async function that converts the input to an output,
> where the outputs can be converted to strings.
> `map_stringify` returns a vector of stringified outputs.
Which function type signature best encodes this specification?
"""
prompt.distractors = [
"""
```rust
async fn example(x: &i32) -> i32 {
sleep(Duration::from_secs(1)).await;
*y
}
async fn map_stringify(
inputs: Vec<String>, f: impl Future<Output = String>
) -> Vec<String>
```
""",
"""
```rust
async fn example(x: Vec<i32>) -> i32 {
sleep(Duration::from_secs(1)).await;
x[0]
}
fn map_stringify<I, O, F>(
inputs: Vec<I>, f: impl Fn(I) -> O,
) -> Vec<impl Future<Output = String>>
where
O: ToString,
```
""",
"""
```rust
async fn example() -> i32 {
let x = 0;
sleep(Duration::from_secs(1)).await;
x
}
async fn map_stringify<I, F>(
inputs: Vec<I>, f: impl Fn(I) -> F,
) -> Vec<String>
where
F: Future + ToString,
```
""",
]
"""]
answer.answer = """
```rust
async fn example(x: i32) -> i32 {
let y = &x;
sleep(Duration::from_secs(1)).await;
*y
async fn map_stringify<I, O, F>(
inputs: Vec<I>, f: impl Fn(I) -> F,
) -> Vec<String>
where
O: ToString,
F: Future<Output = O>,
```
"""
context = """
Here's one implementation of the specified function:
```rust
async fn map_stringify<I, O, F>(
f: impl Fn(I) -> F, inputs: Vec<I>
) -> Vec<String>
where
O: ToString,
F: Future<Output = O>,
{
let f = &f;
let futs = inputs
.into_iter()
.map(|input| async move { f(input).await.to_string() });
futures::future::join_all(futs).await
}
```
"""
id = "b42a9c5b-bfe7-4d6f-967a-f8ff2a6faa0d"

[[questions]]
type = "MultipleChoice"
prompt.prompt = """
Say you are writing a program that needs to run some async code, but every 500ms check to see if the computation should be halted.
Which helper function would be most appropriate for accomplishing this task?
"""
prompt.distractors = [
"`join`",
"`yield`",
"`spawn` / `spawn_task`"
]
answer.answer = "`race` / `select`"
context = """
The core problem addressed by pinning in self-reference, or a future which contains a pointer to itself.
This happens an async block contains a local variable that refers to another local variable in the future.
Here, that would be `y = &x`.
For instance, you could run a `select` in a loop between a long-running future and a sleep future that completes in 500ms.
"""
id = "bc8b4acb-d111-4fec-b89a-e5d1bc77c8f2"
id = "7da21e95-8e03-412b-8c4d-90ccfc8c6802"
82 changes: 0 additions & 82 deletions quizzes/async-04-more-ways-of-combining-futures.toml

This file was deleted.

31 changes: 31 additions & 0 deletions quizzes/async-04-streams.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[[questions]]
type = "MultipleChoice"
prompt.prompt = """
The `Stream` trait is most analogous to which non-async trait in the Rust standard library?
"""
prompt.distractors = ["`Write`", "`Index`", "`Sync`"]
answer.answer = "`Iterator`"
context = """
The `Stream` trait provides an asynchronous version of a Rust iterator.
"""
id = "f94a87f0-a4d6-4cd6-bcee-dfcc606f8ec2"

[[questions]]
type = "MultipleChoice"
prompt.prompt = """
Say you have a stream that produces the sequence `["A", "B", "C"]` and another stream that produces the sequence ["D", "E", "F"].
You do not know when each stream will emit each character, only that it occurs in the specified sequences.
Consider merging these streams and printing each character. Then select each of the following output strings that could print.
"""
prompt.distractors = [
"ACBDEF",
"CFBEAD"
]
answer.answer = [
"ABDEFC",
"DEFABC"
]
context = """
Merging will always respect ordering in each stream, so for example "B" cannot occur before "C".
"""
id = "84452eff-13df-4fcb-91ea-1f504d5bfaf0"
48 changes: 48 additions & 0 deletions quizzes/async-05-traits-for-async.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[[questions]]
type = "MultipleChoice"
prompt.prompt = """
Imagine Rust did not require that futures were pinned in order to be polled.
Which of the following async functions could potentially cause undefined behavior if not pinned?
"""
prompt.distractors = [
"""
```rust
async fn example(x: &i32) -> i32 {
sleep(Duration::from_secs(1)).await;
*y
}
```
""",
"""
```rust
async fn example(x: Vec<i32>) -> i32 {
sleep(Duration::from_secs(1)).await;
x[0]
}
```
""",
"""
```rust
async fn example() -> i32 {
let x = 0;
sleep(Duration::from_secs(1)).await;
x
}
```
""",
]
answer.answer = """
```rust
async fn example(x: i32) -> i32 {
let y = &x;
sleep(Duration::from_secs(1)).await;
*y
}
```
"""
context = """
The core problem addressed by pinning in self-reference, or a future which contains a pointer to itself.
This happens an async block contains a local variable that refers to another local variable in the future.
Here, that would be `y = &x`.
"""
id = "bc8b4acb-d111-4fec-b89a-e5d1bc77c8f2"
3 changes: 3 additions & 0 deletions src/ch17-04-streams.md
Original file line number Diff line number Diff line change
Expand Up @@ -443,4 +443,7 @@ That is a good note to turn to our final section and wrap up this walk through
async in Rust, by discussing how futures (including streams), tasks, and threads
relate to each other, and how you can use them together.

{{#quiz ../quizzes/async-04-streams.toml}}


[17-02-messages]: ch17-02-concurrency-with-async.html#message-passing
2 changes: 2 additions & 0 deletions src/ch17-05-traits-for-async.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,5 @@ and its methods with it automatically.
That’s all we’re going to cover for the lower-level details on these traits. To
wrap up, let’s consider how futures (including streams), tasks, and threads all
fit together!
{{#quiz ../quizzes/async-05-traits-for-async.toml}}

0 comments on commit 3a2eb34

Please sign in to comment.