Idea: non-local control flow

Non-local control flow is a subclass of functions with multiple return points. As also already observed, explicit breaks to outer loops are a very similar feature and implicitely requires that code is structured in nested scopes, and does not permit arbitrary goto. Maybe we could unify them under the break keyword? It doesn't need to be a special feature of closures but it would require expanding the notion of function types. However, to make fold work would require reworking it which may be difficult in a compatible manner. An additional version would pose no problem though.

// A function with two return points. As with reference parameter, 
// requires the caller to provide that the lifetime lives for the full
// function call.
fn mul_early<'early>(acc: i32, num: i32) -> i32, 'early: i32 {
    if num == 0 {
        break 'early 0;
    }
    return acc * num;
}

trait BreakFold {
    type Item;
    
    /// Fold over a function that may return the final value early.
    fn fold<A, F>(&mut self, init: A, f: F) -> A where
        F: (FnMut<'br>(A, Self::Item) -> A, 'br: A);
}

impl<I: Iterator> ManualFold for I {
    type Item = <I as Iterator>::Item;
    
    fn fold<A, F>(&mut self, init: A, mut f: F) -> A where
        F: (FnMut<'br>(A, Self::Item) -> A, 'br: A),
    {
        // The early return provides a value for this block directly.
        'early: {
            let mut acc = init;
            for item in self {
                acc = f::<'early>(acc, item);
            }
            acc
        }
    }
}

This explicit syntax choice would address problems named in the earlier thread:

  • The special meaning compared to normal return is immediately clear, in particular for compiler internals it becomes obvious that the tear-down of the function frame needs to be special cased and potentially performed in a manual way.
  • It's explicit and requires the caller of such a closure/function to explicitely opt-in.
  • It introduces an name for the co-variables that model the code flow.
4 Likes