Would it ever be possible for either of the following to be possible in the rust language because I feel that it could help with conciseness.
Example 1: returning from parent function in a “non-moveable” closure construct
fn foo (c_vec: Vec<C>) -> Result<Vec<D>, ErrorType> {
c_vec.into_iter()
.map('static |c| {
if let Ok(d) = D::try_from(c) {
d
} else {
return 'static ErrorType::new();
}
})
}
I know that the above example is a bit contrived but I have had instances in the past where something like this would have really help but instead I had to use other forms of iteration.
Example 2: using continue and break as “closures”
let list: Vec<Option<_>> = ...;
...
for item in list.iter() {
...
foo.bar(item.unwrap_or_else(continue));
}
I know that it is possible to write the second as an if statement.
The first example is doing a return either from the closure or from foo. Basically, it is trying to convert each item in the vector from a C to a D and if any fails then it returns some error from the outside function. The equivalent code in today’s rust is as follows:
fn foo (c_vec: Vec<C>) -> Result<Vec<D>, ErrorType> {
let mut res = vec![];
for c in c_vec {
if let Ok(d) = D::try_from(c) {
res.push(d);
} else {
return ErrorType::new();
}
}
res
}
A nice property of this style of “closures” is that they compose with control flow constructs, like ? or aync, nicely.
A good example here is Kotlin: because map,filter and friends for collections are implemented using “inline lambdas” (which are macros, semantics-wise), you can just call suspend functions from map over array list. Conversely, you can’t call suspend functions from mapping over lazy Sequences, because that uses a real lambda.
EDIT: to clarify, I don’t think we need this feature in Rust.
What you’re suggesting are continuations (or rather, a subset of them), which I admittedly have been championing for in the long term. That said, any continuation mechanism that lands in Rust will have to have an answer to how they preserve local reasoning, which your suggestion is lacking.
I can do without them, but if they were to be added, I'd like some extra keywords to warn me, eg. mayret, topret, topbreak, topcontinue etc. or whatever:
Or maybe have labeled control flow, eg break :myLoopLabel, like some PLs have.