[ 
https://issues.apache.org/jira/browse/GROOVY-8301?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16259974#comment-16259974
 ] 

mgroovy commented on GROOVY-8301:
---------------------------------

@[~hansj]: First it has to be decided, whether inlining is the way forward - 
then how to best put this feature into Groovy. That's why I called it an 
"inline closure": The way I think of it, when you inline a closure inside the 
scope it captures, there is no need to capture anything - the closure just 
becomes a block construct, same as the block after a for or while loop. The 
properties the "inline closure" share with regular closures is that 1) You can 
pass it to an inlined method (which allows one to implement e.g. custom loops 
with break/continue/return support) 2) It can return a value  (obviously not 
through "return", but through the last expression evaluated) .
The exact semantics of inlining (basically, where and how to mark a 
closure/method to be inlined) is something I hope will be discussed here by 
some of the longtime Groovy developers.

> break/return/continue support in "Appended Block Closures"
> ----------------------------------------------------------
>
>                 Key: GROOVY-8301
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8301
>             Project: Groovy
>          Issue Type: New Feature
>          Components: Compiler
>            Reporter: mgroovy
>              Labels: break, closure, continue, inline, return
>
> This proposal revisits the idea to change the semantics of the break, return, 
> and continue keyword for closures that are used in a way that mimics Java 
> block constructs such as if, for, or while.
> Example 1:
> {code}
> // Iterate over all PERSON rows in the result set
> sqe.forEachRow("select * from PERSON") { final row ->
>   if(row.TAG == 0) { break } // Leave forEachRow loop
>   if(row.TAG == 1) { return } // return from the method enclosing the 
> forEachRow loop
>   if(row.TAG == 2) { continue } // Move to next iteration in the forEachRow 
> loop
> }
> {code}
> Example 2:
> {code}
> // Encapsulate with statically imported helper method that catches exceptions 
> and ignores them, if the passed parameter is true
> execWithOptionalIgnoreErrors(ignoreErrorsQ) {
>   final x = dangerousOperation() 
>   if(x == 1) { return } // return from the enclosing method
>   // Note: break & continue are not allowed here
> }
> {code}
> Support for continue can trivially be mapped to a return statement inside the 
> closure, so what one needs to look at is how to support leaving the iteration 
> ("break" semantics) and returning from the enclosing method ("return" 
> semantics). With current Groovy closures there are two known potential 
> approaches to achieve this behavior:
> # Use try-catch to simulate a non-local goto to "jump" to the right spot.
> ** Described e.g. here 
> http://blackdragsview.blogspot.co.at/2006/09/non-local-transfers-in-groovy-90.html
>  by [~blackdrag].
> ** Drawbacks of the approach:
> ### If the user wraps a try-catch-everything (i.e. catching Exception or 
> Throwable base class) around the code, the mechanism will break in an 
> unexpected way.
> ### Exceptions incur a certain performance overhead.
> # Use special return values that indicate whether to break or return.
> ** This evidently works for all cases which have no return value (e.g. 
> forEach)
> ** For all other cases one could make the closure return an Object, which 
> would again allow to discern regular return values from 
> break/return-semantics return values, if specific classes (e.g. 
> GroovyClosureBreak) are returned
> *** Since casting is required in this case, as small overhead is again 
> incurred
> ** A big drawback is that for both cases for "return" semantics all 
> surrounding methods would need to have / made to have Object as return type.
> ** This approach could be used to supply "continue" and "break" semantics 
> only.
> *** Note that having more than one return in a method is also often 
> considered bad style, so one could argue that "continue" and "break" 
> semantics are the more important of the three to support.
> A different approach would be to introduce "inline closures" to Groovy. These 
> closures would effectively be treated as inline block constructs, the same as 
> they already exist for e.g. regular for loops. This feature would make 
> contine/break/return support for "closures" trivial, since the keywords would 
> just automatically work as expected if the closure code is inlined.
> * This approach is used e.g. by the Kotlin programming language 
> https://kotlinlang.org/docs/reference/inline-functions.html
> * Kotlin uses a seperate "inline" keyword for this. I feel like supplying an 
> annotatio in Groovy to indicate inlining would be the more Groovy/flexible 
> (can be combined with other annotations) approach (Kotlin to me generally 
> seems to suffer from an overabundance of keywords)
> * Allowing inlining is also a feature that could also be applied for general 
> methods.
> * Leaving implementation effort aside, this approach to me looks like the 
> best way forward, it
> ## never breaks
> ## never incurs any performance overhead
> ## is elegant
> ## potentially can be used for applications that go beyond the topic of this 
> issue
> * Note: The general version of this feature has already been suggested in 
> GROOVY-6880 with regards to performance improvements. I agree that potential 
> performance improvements are not a strong enough argument to introduce this, 
> automatic break/contine/return support for inlined closures to me is.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to