#439 Break as an Exception

JohnDG Thu 22 Jan 2009

I'd like to propose that when break appears outside of a loop, it be translated into a new BreakException. This allows us to break out of custom control flow constructs like each, without forcing us to return a value every single time (which is pretty much boilerplate).

A BreakException will naturally bubble until it is caught. It could be caught automatically by any built-in loop construct. Or, if used inside a closure, it could be caught by whatever function is calling the closure (as in the case of each).

Void each(|V item, Int index| c) {
   try {
       for (i := 0; i < size; i++) {
           try {
               c(array[i], i)
           }
           catch (ContinueException e) {
           }
       }
   }
   catch (BreakException e) {
   }
}

JohnDG Fri 23 Jan 2009

Continuing this idea to see how far it leads...

while

Void while(lazy Bool condition, |,| block) {
    try {
        if (condition()) {
            try {    
                block()
            }
            catch (ContinueException e) {
            }

            while(condition, block)
        }
    }
    catch (BreakException e) {
    }
}

for

Void for(lazy Void initial, lazy Bool condition, lazy Obj increment, |,| block) {
    initial()

    try {
        if (condition()) {
            try {
                block()
            }
            catch (ContinueException e) {
            }

            increment()

            for(null, condition, increment, block)
        }
    }
    catch (BreakException e) {
    }
}

These implementations would never be used in real-life, of course. This is just a way of exploring how to unify built-in and user-specified control structures.

helium Sat 24 Jan 2009

initial is allways evaluated first and never re-evaluated. So why pass it by need?

(BTW, I don't think that Fan has tailcalls)

JohnDG Sat 24 Jan 2009

You're right, it should be Void initial. And yes, Fan has no tail calls but if you want to implement the core looping constructs in the language itself, you have to use recursion. :-) The examples are purely for illustration, not for actual use.

Login or Signup to reply.