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