3 ms·
The main criticism expressed in this blog post is that in Rust, transforming a language construct into a seemingly equivalent one (typically using .map()) works
by rom1v 4y ago
The main criticism expressed in this blog post is that in Rust, transforming a language construct into a seemingly equivalent one (typically using .map()) works in some cases (described as the "hello world" cases, which might be a bit exaggerated), but sometimes not (due to lifetime, fallibility, async…).
For example, this code (real world example from two days ago):
fn main() {
let value = None;
let _processed_value = match value {
Some(value) => Some(process(value)),
None => None,
};
}
fn process(_value: u32) {}
can be transformed into this equivalent form:
fn main() {
let value = None;
let _processed_value = value.map(|value| process(value));
}
fn process(_value: u32) {}
But in async Rust, this code works:
#[tokio::main]
async fn main() {
let value = None;
let _processed_value = match value {
Some(value) => Some(process(value).await),
None => None,
};
}
async fn process(_value: u32) {}
But this one does not work:
#[tokio::main]
async fn main() {
let value = None;
let _processed_value = value.map(|value| process(value).await);
}
async fn process(_value: u32) {}
It fails with the following error:
error[E0728]: `await` is only allowed inside `async` functions and blocks
--> src/main.rs:4:64
|
4 | let _processed_value = value.map(|value| process(value).await);
| ------- ^^^^^^ only allowed inside `async` functions and blocks
| |
| this is not `async`
This is basically what is described as the sandwich problem: https://blog.rust-lang.org/inside-rust/2022/07/27/keyword-generics.html#a-taste-of-trouble-the-sandwich-problem https://blog.rust-lang.org/inside-rust/2022/07/27/keyword-ge...
I have to admit that I often need to refactor parts of code while I'm writing Rust code due to such issues, so I understand the author's point of view.