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
> >>
> >
> 

Reply via email to