Hi Mario, I think you have got the point of the proposal ;-)
If we prefer the verbose but clear syntax, I think we could introduce `_` to represent the return value for concise shape: ``` return callB() if (_ != null && _ > 10) // The following code is like lambda expression, which is a bit more verbose return callB() if (result -> result != null && result > 10) ``` Show the `_` usage in your example: ``` def doSomething(int a) { return callB() if (a > 6 && _ > 10) return callC() if (a > 5 && _ > 20) return callD() if (a > 4 && _ > 30) } ``` ``` // optional parentheses def doSomething(int a) { return callB() if a > 6 && _ > 10 return callC() if a > 5 && _ > 20 return callD() if a > 4 && _ > 30 } ``` ``` // one more example def doSomething(int a) { return callB() if a > 6 && _ > 10 return callC() + callD() if a > 5 && _ > 50 } ``` BTW, the parentheses behind `if` could be optional. Cheers, Daniel Sun On 2020/07/26 11:29:39, Mario Garcia <mario.g...@gmail.com> wrote: > Hi all: > > Very interesting topic. > > The first idea sprang to mind was the PMD rule in Java saying you should > have more than one exit point in your methods ( > https://pmd.github.io/latest/pmd_rules_java_codestyle.html#onlyonereturn). > But the reality is that sometimes (more often than not) we are forced to > break that rule. In fact sometimes we could even argue that breaking that > rule makes the code clearer (e.g > https://medium.com/ncr-edinburgh/early-exit-c86d5f0698ba) > > Although my initial reaction was to be against the proposal, however after > doing some coding, I've found that neither elvis nor ternary operators > makes it easier nor clearer. Here's why I think so. Taking Daniel's example: > > ``` > def m() { > def a = callA() > if (null != a) return a > > def b = callB() > if (b > 10) return b > > def c = callC() > if (null != c && c < 10) return c > > LOGGER.debug('the default value will be returned') > > return defaultValue > } > ``` > The shortest elvis operator approach I could think of was: > ``` > def m2() { > return callA() > ?: callB().with { it > 10 ? it : null } > ?: callC().with { null != it && it <10 ? it : null } > } > ``` > > which to be honest, is ugly to read, whereas Daniel's proposal is just: > > ``` > def m() { > return? callA() > return(r -> r > 10) callB() > return(r -> null != r && r < 10) callC() > return defaultValue > } > ``` > > Once said that, I would say this conditional return could be useful only > when there are more than two exit points, otherwise ternary or elvis > operators may be good enough. > > So, bottom line, I kinda agree to add conditional return, but I'm not sure > about the final syntax: > > ``` > return(r -> r > 10) callB() > return callB() [r -> r > 10] > return callB() if (r -> r > 10) > ``` > > Between the three I the one that I like the most is the third one: > > ``` > return callB() if (r -> r > 10) > ``` > > You can read it in plain english as "return this if this condition > happens". > > Apart from Daniel's use case, using this option could open the > possibility to use, not only a closure or lambda expression, but also a > plain expression. A nice side effect could be that something like the > following code: > > ``` > def doSomething(int a) { > return callB() if a > 6 > return callC() if a > 5 > return callD() if a > 4 > } > ``` > > turns out to be a shorter (and in my opinion nicest) way of switch case > (when you want every branch to return something): > > ``` > def doSomething(int a) { > switch (a) { > case { it > 6 }: return callB() > case { it > 5 }: return callC() > case { it > 4 }: return callD() > } > } > ``` > > Well, bottom line, I'm +1 Daniel's proposal because I've seen some cases > where this conditional return could make the code clearer. > > Cheers > Mario > > El sáb., 25 jul. 2020 a las 23:55, Paolo Di Tommaso (< > paolo.ditomm...@gmail.com>) escribió: > > > It's not much easier a conditional expression (or even the elvis > > operator)? > > > > ``` > > def m() { > > def r = callSomeMethod() > > return r != null ? r : theDefaultResult > > } > > ``` > > > > > > On Sat, Jul 25, 2020 at 8:56 PM Daniel Sun <sun...@apache.org> wrote: > > > >> Hi all, > >> > >> We always have to check the returning value, if it match some > >> condition, return it. How about simplifying it? Let's see an example: > >> > >> ``` > >> def m() { > >> def r = callSomeMethod() > >> if (null != r) return r > >> > >> return theDefaultResult > >> } > >> ``` > >> > >> How about simplifying the above code as follows: > >> ``` > >> def m() { > >> return? callSomeMethod() > >> return theDefaultResult > >> } > >> ``` > >> > >> Futhermore, we could make the conditional return more general: > >> ``` > >> def m() { > >> return(r -> r != null) callSomeMethod() // we could do more checking, > >> e.g. r > 10 > >> return theDefaultResult > >> } > >> ``` > >> > >> Any thoughts? > >> > >> Cheers, > >> Daniel Sun > >> > > >