Sunday, January 13, 2008

Non-local returns - two returns

The BGGA Closure proposal for Java has two types of return.

- One type is the normal return from methods.
- The other is a return from closures.

The destinction is needed because closures is used to implement control structures, and need to act as both expressions and statements in the control structure. Statements passed as a closure to a control structure, are allowed to return from the method enclosing the control structure invocation. The normal return is used for this. Closures returning a value to their invoker instead put an expression at the end of the closure literal and implicitly return this value (like, e.g., Perl syntax).

I think it was Tennent who said something lke: "You should have either zero, one, or an infinite amount of any feature". Not two.

If you have a closure within a closure, there is no simple way to make the inner closure return from the outer one. Closure returns can only appear in one place (at the end). Methods and closures are needlessly different.

I would suggest a more general solution. Now, the big question is, can I come up with one, or is this just unconstructive whining.

Java has solved nested scope problems before, when they introduced nested classes, and from the begining with breaking from nested loops. The solution was always to refer to anything but the closest enclosing instance by name.
You refer to an outer instance as "OuterClass.this". You break from an outer loop as "break outerLoopLabel".

What would the corresponding returns be like?

The simple version is that an unqualfied "return" means return from the innermost closure, and "MethodName.return" returns from the method. That still needs something for nested closures. Let's give the outer closure a name, and write "closureName.return" to return from it. Syntax for naming could be putting a label before a closure literal, i.e.,
closureName:{int x => ... {int y => ... closureName.return 42; ... }...}

However, this fails to properly hide the closure nature in control structures. Part of the effort on control structures is trying to make the code you write inside the closure the same as the code you would write in a language defined control structure (like "for" and "while"). A "return" in there would refer to the enclosing method.

If we let "return" mean return from the (only) enclosing method, we still need to name closures to allow non-local closure return, e.g., as labels above. But that means you will need to name the innermost closure too and return from them using a named return. Not pretty either. It makes it more inconvenient to parameterize control structures with expressions. Ofcourse, we can add the existing local return syntax (expression-at-the-end) as a shorthand for returning from the closest enclosing closure.

All in all, I think I would probably prefer a special syntax for control structures, rather than let them complicate general closures.

No comments: