Skip to content

Commit

Permalink
More quizzes
Browse files Browse the repository at this point in the history
  • Loading branch information
willcrichton committed Aug 31, 2024
1 parent 754549f commit 2f5ce3b
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 5 deletions.
46 changes: 41 additions & 5 deletions quizzes/async-03-more-futures.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ let futs: Vec<_> = [1, 2, 3].iter().map(|n| async {
sleep(Duration::from_secs(5)).await;
n + 1
}).collect();
for fut in futs {
let n = fut.await;
println!("{n}");
Expand All @@ -26,13 +27,48 @@ 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 best describes the kind of problem that could occur?
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 = [
"If a future were movable at any point in its lifetime, then ..."
"""
```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 = "If a future contains a reference to itself, then moving the future between polls would violate memory safety"
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 = "1c3b2ad9-d9af-48b1-8cdf-bfc658ec456b"

id = "bc8b4acb-d111-4fec-b89a-e5d1bc77c8f2"
82 changes: 82 additions & 0 deletions quizzes/async-04-more-ways-of-combining-futures.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
[[questions]]
type = "MultipleChoice"
prompt.prompt = """
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 map_stringify(
inputs: Vec<String>, f: impl Future<Output = String>
) -> Vec<String>
```
""",
"""
```rust
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 map_stringify<I, F>(
inputs: Vec<I>, f: impl Fn(I) -> F,
) -> Vec<String>
where
F: Future + ToString,
```
"""]
answer.answer = """
```rust
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
}
```
"""

[[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?
"""
answer.answer = "`race` / `select`"
prompt.distractors = [
"`join`",
"`yield`",
"`spawn` / `spawn_task`"
]
context = """
For instance, you could run a `select` in a loop between a long-running future and a sleep future that completes in 500ms.
"""
3 changes: 3 additions & 0 deletions src/ch17-04-more-ways-of-combining-futures.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,4 +292,7 @@ Over the last two sections, we have seen how to work with multiple futures at
the same time. Up next, let’s look at how we can work with multiple futures in a
sequence over time, with *streams*.

{{#quiz ../quizzes/async-04-more-ways-of-combining-futures.toml}}


[futures]: ch17-01-futures-and-syntax.html#what-are-futures

0 comments on commit 2f5ce3b

Please sign in to comment.