jastrachan | 26 Jan 16:41 2005

Re: [groovy-dev] Diff of Java and Groovy grammars

On 26 Jan 2005, at 15:08, Martin C. Martin wrote:
> jastrachan@... wrote:
>> On 26 Jan 2005, at 14:26, Russel Winder wrote:
>> The use case for the optional return came from wanting clean GPath 
>> expressions. Actually, thinking through further, the 'return' should 
>> not really be used anyway in a closure, as it doesn't mean 'return 
>> from function'. In which case, maybe things really are a whole lot 
>> simpler and we can then make return is mandatory in all 
>> functions/methods - its just not required in closures.
>> i.e.
>> String foo() {
>>    while (something) {
>>         coll.each { |p| if (p == 1000) { return } else println p }
>>    }
>> }
>> The 'return' in the above should return from the function foo().
>> So the 'optional' return disappears - return is now mandatory on 
>> functions/methods, but closures don't use return (in the same way at 
>> least) and the last expression in the block is the value returned to 
>> the caller of the closure.
>> Thoughts?
> This works well when the closure is used in one place, and executed 
> when it's defined, as above.  As a callback, though, it's less clear.  
> If I use a closure as an actionPerformed callback, what would a 
> "return" statement return from?

 From a method, which invokes the closure (assuming its been developed 
to be able to handle such a thing). Clearly if you're using a closure 
as a method pointer (like a Java Bean listener method like Runnable or 
ActionListener, then it will have no effect).

>  If I write a function that takes a closure, I may not want the 
> closure to be able to exit my function, at least not without cleaning 
> up.

Its up to you to handle the request for a return however you want. You 
can use finally { } to clean up - or just gobble up the exceptions. So 
the caller of the closure is in full command over what to do. (We'll 
probably need two mechanisms to invoke closures, one in Groovy land 
that does all the exception handling for you, and one that just gobbles 
them up).

> For example, if I'm doing some numerical processing and with to find 
> an x such that f(x) = 0, I don't want f() to be able to exit from my 
> zero finder.

Sure - like I said its your call. However you may want to be able to 
abort a lengthy iteration by the closure deciding when to stop.


doSomethingSlow(Closure c) {
   for (i in 0..someLargeNumber) {

doSomethingSlow { i | if (i > 1000) { return } else { println i }}

> In that case, I suspect people treat it more like a function, whereas 
> in the former, it's more like a statement block.

Yes. Closures really are more like statement blocks really; though they 
can be used as a function - when being used as a function the 
break/return logic might not be used.