jastrachan | 1 Feb 16:55 2005

Re: thoughts on the closure/return/break/continue issue

One other thought on this proposal.

The syntax rules for return statements in methods/functions seems quite 
different to those in closures, which feels a little smelly. Maybe they 
should have the same shape/feel?

So how about this minor change...

>> return rules
>> ============
>> So return, break, continue should work the same at any point in a 
>> method body - whether it happens to be in a closure block or not.
>> The basic rule on return is that it is mandatory at the end of any 
>> non-void method body. Clearly there is no equivalent 'return' inside 
>> the closure call as return only means, return from a method call (not 
>> a closure invocation).
>> For closures, the last expression in the closure is returned to the 
>> invoker of the closure - or null if there is no expression or the 
>> expression has no value.

Rather than the above, it might be easier & simpler to say the 
following are the rules for return/continue statements...

(i) Method bodies and closure blocks with a single expression do not 
need a return/continue statement.

def foo() {
    bar * 5

coll.collect { it * 5 }
coll.collect { (it == 5) ? 1 : 0 }

Both of which work as a nice short hand, they're super easy to test for 
& there are no edge cases and GPath then keeps looking cute.

(ii) method bodies and closures which return a value and have more than 
one expression/statement, must use a return or continue statement

This makes the syntax more explicit but hopefully makes it easier to 
catch typeos and makes the syntax more readable...

def foo() {
     println "abc"
     return bar *5

coll.collect { if (it > 123) { println "hey"; continue 1} else { 
continue 0 }}

>> no dumb expression rule
>> =======================
>> We have a no-dumb-expression rule to catch bad expression & typos 
>> (like line terminators in the wrong place)
>> def foo() {
>>   x = 5
>>   +5	// dumb expression, probably didn't mean a line terminate here
>>   return 2
>> }
>> no dumb expression rule in closures
>> ===================================
>> We allow the last expression inside a closure to be a dumb 
>> expression, but previous ones cannot be.
>> list.each { def y = it + 1; +5; y }  // +5 is a dumb expression

If we use the above 2 rules for return/continue, we could then further 
simplify the no-dumb-expression rules further to...

(iii) unless a method body or closure is a single expression, then no 
dumb expressions are allowed anywhere in the block.

These 3 rules are then much simpler - way easier to remember, 
polymorphic across method bodies and closures and keep GPath nice and 
neat and enforce mandatory 'terminate method/block with value' syntax 
mandatory & explicit in all but the most simple of cases. So we should 
catch the maximum of typeos, have a strong no-dumb-expression rule yet 
have a similar feel for blocks, closures and method bodies