Skip to end of metadata
Go to start of metadata

Question

Using the return keyword in a closure means to return from the method containing the closure. This naturally leads to the question of what happens when you have a closure containing a return that was created in a function that has now gone out of scope, and that closure is executed. For example:

def f() {
    return {return 2} // returns a closure containing a return
}

def g() {
    def myClosure = f()
    myClosure() // tries to return from f(), but f() is out of scope
}

Decision

In this situation, Groovy will cause a RuntimeException to be thrown.

Rationale

John Rose offers the following rationale:

Out-of-scope return is a corner case which has been addressed adequately in the Smalltalk and Common Lisp standards. As such it is a solved problem which we can incorporate directly into Groovy. (FTR, Scheme solves it differently, at a high architectural cost. I am aware of no third workable solution.)

Basically, the return works as long as the closure executes that return at some time during the call to the method that created the closure. Such a "non-local" return will internally use the JVM's exception mechanisms. Under the covers it is moderately complex (like other closure or inner-class mechanics) but the user sees return statements that "just work".

After the creating method returns (either locally or non-locally), it cannot return again.
Therefore, the closure can survive and be useful, until and unless it tries to execute the return; at that point an error must be thrown. Compare this error to errors which are thrown when a monitorexit instruction is executed on an unlocked monitor, when a class fails to link, etc.

(BTW, some have tried to give a meaning to a return out of a method that has already exited. Apart from Scheme's answer, I think this leads to unsafe, subtly buggy nonsense. Asking for the meaning of an out-of-scope return is like asking for the meaning of a monitorexit on an unlocked monitor, or the proverbial one hand clapping.)

Email threads:

  • No labels