Hi,

this is Brian Goetz initial idea
https://cr.openjdk.java.net/~briangoetz/amber/pattern-match.html

And these are the related JEPs
https://openjdk.java.net/jeps/361
https://openjdk.java.net/jeps/375

and this is the umbrella project amber
https://openjdk.java.net/projects/amber/

cheers

- Leo

Am 10.08.2020 um 15:28 schrieb Milles, Eric (TR Technology):
>
> The current state of Java's switch expression is described briefly
> here: 
> https://docs.oracle.com/en/java/javase/13/language/switch-expressions.html
> <https://docs.oracle.com/en/java/javase/13/language/switch-expressions.html>
>  They are a stepping stone to introducing pattern matching.  First
> step is statement -> expression and multi case.  This new syntax
> creates a gap between Java and Groovy.  And I think Groovy should
> support Java syntax as best as possible.
>
>  
>
> *From:* MG <mg...@arscreat.com>
> *Sent:* Friday, August 7, 2020 3:37 PM
> *To:* dev@groovy.apache.org; Milles, Eric (TR Technology)
> <eric.mil...@thomsonreuters.com>
> *Subject:* Re: switch destructuring
>
>  
>
> Hi eric,
>
> just to make my post clear: I do not desperately need pattern
> matching, but I know from experience that (full blown) pattern
> matching is a very powerful feature (I implemented automatic series
> expansion of quantum field theory Green functions through functional
> derivatives using Mathematicas pattern matching), so it would
> certainly be cool to have something along that line, if we have the
> manpower to do it (not Prolog/Mathematica level, but powerful) :-)
>
> With regards to Java: Do you have a link of what exactly we are
> talking about ? I do not use Java, and every time I read something
> about pattern matching in Java, it looks to me like the current
> features set is quite limited - but there are grand plans for the
> future...
>
> Cheers,
> mg
>
> On 07/08/2020 20:46, Milles, Eric (TR Technology) wrote:
>
>     There is a pattern match syntax that is implemented using Groovy
>     macros so that you can use the match "keyword". 
>     
> https://github.com/bsideup/groovy-pattern-match/blob/feature/dsl-like-matching/src/test/groovy/ru/trylogic/groovy/pattern/PatternMatchingMacroMethodsTest.groovy
>     
> <https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fbsideup%2Fgroovy-pattern-match%2Fblob%2Ffeature%2Fdsl-like-matching%2Fsrc%2Ftest%2Fgroovy%2Fru%2Ftrylogic%2Fgroovy%2Fpattern%2FPatternMatchingMacroMethodsTest.groovy&data=02%7C01%7Ceric.milles%40thomsonreuters.com%7C9a342f22ade649706de008d83b11a879%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637324294328813293&sdata=O2Lv7mrHdcrGmlPIJPrco70L0Zic0ahiRfQ9biOdZec%3D&reserved=0>
>  
>     The current version is more DSL-like using "when", "then" and
>     "orElse" instead of operators.
>
>      
>
>     There was an earlier version that used case as "when", | as "or"
>     and >> as "then". 
>     
> https://github.com/bsideup/groovy-pattern-match/blob/master/src/test/groovy/ru/trylogic/groovy/pattern/PatternMatchingMacroMethodsTest.groovy
>     
> <https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fbsideup%2Fgroovy-pattern-match%2Fblob%2Fmaster%2Fsrc%2Ftest%2Fgroovy%2Fru%2Ftrylogic%2Fgroovy%2Fpattern%2FPatternMatchingMacroMethodsTest.groovy&data=02%7C01%7Ceric.milles%40thomsonreuters.com%7C9a342f22ade649706de008d83b11a879%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637324294328813293&sdata=iIsOVic%2BhxcBWjc9IYc%2FLhu4ThmfrO32uOrUw4x951k%3D&reserved=0>
>
>      
>
>      
>
>     In terms of what Groovy supports right now, you can use closures
>     for each case in a switch statement and check anything you want
>     about the expression supplied to the switch or the context around
>     the switch statement.
>
>      
>
>     I agree with Paul that supporting Java's switch expression
>     enhancements would cover a lot of common cases.  Then we could
>     regroup and see what sort of edge cases remain and if there is
>     merit in adding something to help with them.
>
>      
>
>      
>
>     *From:* MG <mg...@arscreat.com> <mailto:mg...@arscreat.com>
>     *Sent:* Friday, August 7, 2020 12:41 PM
>     *To:* dev@groovy.apache.org <mailto:dev@groovy.apache.org>; Paul
>     King <pa...@asert.com.au> <mailto:pa...@asert.com.au>
>     *Subject:* switch destructuring
>
>      
>
>     Hi Paul,
>
>     the Python destructuring sure looks powerful (I did my master
>     thesis in Mathematica, which is all about pattern matching).
>     Here is one of the Python examples in a potential Groovy syntax,
>     which tries to convert its argument into a  3D-point:
>
>     @Newify(pattern=/[A-Z][A-Za-z0-9_]+/)
>     Point3d makePoint3d(final point3dCandidate) {
>         match(point3dCandidate) {
>             case [Number x, Number y]:
>                 return Point3d(x, y, 0)
>             case [Number x, Number y, Number z]:
>                 return Point3d(x, y, z)
>             case Point2d(x, y):
>                 return Point3d(x, y, 0)
>             case Point3d(_, _, _):
>                 return point3dCandidate
>             default:
>                 throw TypeError("${NV(point3dCanditate) could not be
>     converted to Point3D")
>       }
>     }
>
>     Cheers,
>     mg
>
>
>     On 07/08/2020 12:53, Paul King wrote:
>
>         I created a starting set of NV, NVI and NVD macros similar
>         (but slightly different) to what mg has described previously.
>         I see that as a starting point for discussion.
>
>          
>
>         Something like 'returnIf' wouldn't be hard to add but I'd
>         personally prefer to explore enhancing our switch statement
>         first since I think that would cover many use cases where I'd
>         be tempted to try 'returnIf'.
>
>          
>
>         Just on switch statements we have Java 13/14 enhanced switch
>         we could explore (switch expressions, yields/no breaks) and
>         destructuring like python's latest proposal[1] but obviously
>         with our own syntax.  
>
>          
>
>          
>
>         Cheers, Paul.
>
>         [1] https://www.python.org/dev/peps/pep-0622/
>         
> <https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.python.org%2Fdev%2Fpeps%2Fpep-0622%2F&data=02%7C01%7Ceric.milles%40thomsonreuters.com%7C9a342f22ade649706de008d83b11a879%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637324294328823285&sdata=OCubQGfqRfvKkOO2mAT%2FhgZU6lyGuuj6GyztcKSocKk%3D&reserved=0>
>
>          
>
>         On Wed, Aug 5, 2020 at 7:53 AM MG <mg...@arscreat.com
>         <mailto:mg...@arscreat.com>> wrote:
>
>             Hi Eric,
>
>             yea,  I got that, that's why I said "In that case a global
>             setting might /also/ be useful".
>
>             But I doubt that the majority of Groovy users out there
>             who want to quickly check if it is macros that make their
>             code break in Groovy 4 would know that to do so they just
>             need to "add the macro transform class to the disallowed
>             list in CompilerConfiguration";  to be able to do so would
>             mean one would a) need to know the macro transform class
>             exists and what its purpose and exact name is, b) how the
>             disallowed list in CompilerConfiguration works (that's the
>             easy part), as well as last but not least c) to be sure
>             that doing so will not just break part or all of Groovy... ;-)
>
>             I think you grossly underestimate the amount of Groovy
>             (internal) knowledge you have :-)
>
>             Cheers,
>             mg
>
>
>             On 04/08/2020 18:27, Milles, Eric (TR Technology) wrote:
>
>                 In terms of globally disabling macro methods, you can
>                 just add the macro transform class to the disallowed
>                 list in CompilerConfiguration.  I think Paul is
>                 describing a mechanism where an individual macro
>                 method is taken out of service.
>
>                  
>
>                 *From:* MG <mg...@arscreat.com>
>                 <mailto:mg...@arscreat.com>
>                 *Sent:* Tuesday, August 4, 2020 9:53 AM
>                 *To:* dev@groovy.apache.org
>                 <mailto:dev@groovy.apache.org>; Paul King
>                 <pa...@asert.com.au> <mailto:pa...@asert.com.au>
>                 *Subject:* Re: [PROPOSAL]Support conditional return
>
>                  
>
>                 Hi Paul,
>
>                 thanks for clearing that up :-)
>
>                 @unforeseen implications: In that case a global
>                 -Dgroovy.macro.enable=false
>                 might also be useful, to do a quick check if it is
>                 macros that are causing the problem (if we do not have
>                 that already).
>
>                 Btw: Do we have a way to hide the macro definitions
>                 from e.g. IntelliJ Intellisense, and only show the
>                 stub implementation ? I use the NV macros* extensively
>                 by now in my code, and what I found is, that always
>                 having to select and import the stub class, and not
>                 the macro class is a (small) hassle.
>
>                 Cheers,
>                 mg
>
>                 *In practice it turns out the NV variety I use the
>                 most is NVL, which returns a list of NV instances, so
>                 is good for logging multiple variables. At some point
>                 in the future there will need to be a discussion what
>                 varieties we want to support; my suggestion would be:
>                 NV(x) ... single NameAndValue class instance
>                 NVL(x0,x1,...) ... list of NameAndValue instances
>                 NVS(x0,x1,...) ... "x0=$x0, x1=$x1, ..."-GString
>                 (we could also have NVS return an (efficiently built)
>                 String, and NVGS return the GString, but I am not sure
>                 whether that it is worth it)
>
>                 On 04/08/2020 08:17, Paul King wrote:
>
>                      
>
>                     Hi mg,
>
>                      
>
>                     Just on supplying our own macros, we should do
>                     this for Groovy 4. We have been reluctant so far
>                     because we have been conservative about unforeseen
>                     implications. However, unless we start using them
>                     more widely, we aren't going to learn those
>                     implications.
>
>                      
>
>                     I'd suggest having them (to start with) in their
>                     own optional incubating module (e.g.
>                     groovy-macro-samples) and we should come up with a
>                     way to disable any one of them, e.g.
>                     -Dgroovy.macro.enable.returnIf=false 
>                     -Dgroovy.macro.enable.NV=true (or whatever).
>
>                      
>
>                     Cheers, Paul.
>
>                      
>
>                     On Wed, Jul 29, 2020 at 10:07 AM MG
>                     <mg...@arscreat.com <mailto:mg...@arscreat.com>>
>                     wrote:
>
>                         I like that idea :-)
>                         (unless someone has a really convincing
>                         argument why not, 100% for
>                         sticking with "it" instead of "_"/"$")
>
>                         That would also allow for more flexibility
>                         with e.g. regards to the
>                         number of methods that are being evaluated,
>                         without getting into the
>                         problematic area of whether/ how to support
>                         this syntax-wise.
>
>                         If there is nothing blocking this, the
>                         question is if Groovy should
>                         supply a basic version of such a macro (if
>                         Groovy is ever planning to
>                         supply macros of its own) ?
>
>                         Cheers,
>                         mg
>
>
>                         On 28/07/2020 16:08, Milles, Eric (TR
>                         Technology) wrote:
>                         > If switch expression or pattern match macro
>                         is insufficient, could a macro be written to
>                         cover this "conditional return"?
>                         >
>                         > // "it" could easily be replaced by "_" or
>                         "$" as mentioned previously as options
>                         > def doSomething(int a) {
>                         >    returnIf(callB(), a > 6 && it > 10)
>                         >    returnIf(callC(), a > 5 && it > 20)
>                         >    returnIf(callD(), a > 4 && it > 30)
>                         > }
>                         >
>                         >    vs.
>                         >
>                         > def doSomething(int a) {
>                         >    return callB() if (a > 6 && _ > 10)
>                         >    return callC() if (a > 5 && _ > 20)
>                         >    return callD() if (a > 4 && _ > 30)
>                         > }
>                         >
>                         > -----Original Message-----
>                         > From: Daniel Sun <sun...@apache.org
>                         <mailto:sun...@apache.org>>
>                         > Sent: Sunday, July 26, 2020 6:23 PM
>                         > To: dev@groovy.apache.org
>                         <mailto:dev@groovy.apache.org>
>                         > Subject: Re: [PROPOSAL]Support conditional
>                         return
>                         >
>                         > Hi Sergei,
>                         >
>                         > ( Copied from twitter:
>                         
> https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Ftwitter.com%2Fbsideup%2Fstatus%2F1287477595643289601%3Fs%3D20&amp;data=02%7C01%7Ceric.milles%40thomsonreuters.com%7C411c66fda05844d7429908d831bacc9d%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637314025668554080&amp;sdata=vNa3dz0H%2BJAegS9Zb8HW2by0ueceqCKI6qDVFpBpbc4%3D&amp;reserved=0
>                         
> <https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Ftwitter.com%2Fbsideup%2Fstatus%2F1287477595643289601%3Fs%3D20&data=02%7C01%7Ceric.milles%40thomsonreuters.com%7C9a342f22ade649706de008d83b11a879%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637324294328823285&sdata=Vh1n4VwcMyo3ArbnYnEmETZE0vRnqqHCOhSU4jsvKBA%3D&reserved=0>
>                         )
>                         >> But isn't it better with pattern matching?
>                         And what is "_" here?
>                         > The underscore represents the return value
>                         >
>                         >> Anyways:
>                         >> ```
>                         >> return match (_) {
>                         >>      case { it < 5 }: callC();
>                         >>      case { it > 10 }: callB();
>                         >>      case { it != null }: callA();
>                         >>      default: {
>                         >>          LOG.debug "returning callD"
>                         >>          return callD()
>                         >>      }
>                         >> }
>                         >> ```
>                         > pattern matching may cover some cases of
>                         Conditional Return, but it can not cover all.
>                         Actually the Conditional Return is more
>                         flexible, e.g.
>                         >
>                         > ```
>                         > def chooseMethod(String methodName, Object[]
>                         arguments)  {
>                         >     return doChooseMethod(methodName,
>                         arguments) if _ != null
>                         >
>                         >     for (Class type : [Character.TYPE,
>                         Integer.TYPE]) {
>                         >        return doChooseMethod(methodName,
>                         adjustArguments(arguments.clone(), type)) if _
>                         != null
>                         >     }
>                         >
>                         >     throw new
>                         GroovyRuntimeException("$methodName not
>                         found") } ```
>                         >
>                         > Even we could simplify the above code with
>                         `return?` if the condition is Groovy truth:
>                         > ```
>                         > def chooseMethod(String methodName, Object[]
>                         arguments)  {
>                         >     return? doChooseMethod(methodName,
>                         arguments)
>                         >
>                         >     for (Class type : [Character.TYPE,
>                         Integer.TYPE]) {
>                         >        return? doChooseMethod(methodName,
>                         adjustArguments(arguments.clone(), type))
>                         >     }
>                         >
>                         >     throw new
>                         GroovyRuntimeException("$methodName not
>                         found") } ```
>                         >
>                         > Cheers,
>                         > Daniel Sun
>                         > On 2020/07/26 18:23:41, Daniel Sun
>                         <sun...@apache.org <mailto:sun...@apache.org>>
>                         wrote:
>                         >> Hi mg,
>                         >>
>                         >>> maybe you can give some real life code
>                         where you encounter this on a regular basis ?
>                         >> Let's think about the case about choosing
>                         method by method name and arguments:
>                         >>
>                         >> ```
>                         >> def chooseMethod(String methodName,
>                         Object[] arguments) {
>                         >>     def methodChosen =
>                         doChooseMethod(methodName, arguments)
>                         >>     if (null != methodChosen) return
>                         methodChosen
>                         >>
>                         >>     methodChosen =
>                         doChooseMethod(methodName,
>                         adjustArguments(arguments.clone(),
>                         Character.TYPE))
>                         >>     if (null != methodChosen) return
>                         methodChosen
>                         >>
>                         >>     methodChosen =
>                         doChooseMethod(methodName,
>                         adjustArguments(arguments.clone(), Integer.TYPE))
>                         >>     if (null != methodChosen) return
>                         methodChosen
>                         >>
>                         >>     throw new
>                         GroovyRuntimeException("$methodName not
>                         found") } ```
>                         >>
>                         >> The above code could be simplified as:
>                         >> ```
>                         >> def chooseMethod(String methodName,
>                         Object[] arguments) {
>                         >>     return? doChooseMethod(methodName,
>                         arguments)
>                         >>
>                         >>     return? doChooseMethod(methodName,
>                         >> adjustArguments(arguments.clone(),
>                         Character.TYPE))
>                         >>
>                         >>     return? doChooseMethod(methodName,
>                         >> adjustArguments(arguments.clone(),
>                         Integer.TYPE))
>                         >>
>                         >>     throw new
>                         GroovyRuntimeException("$methodName not
>                         found") } ```
>                         >>
>                         >> Or a general version:
>                         >> ```
>                         >> def chooseMethod(String methodName,
>                         Object[] arguments) {
>                         >>     return doChooseMethod(methodName,
>                         arguments) if _ != null
>                         >>
>                         >>     return doChooseMethod(methodName,
>                         >> adjustArguments(arguments.clone(),
>                         Character.TYPE)) if _ != null
>                         >>
>                         >>     return doChooseMethod(methodName,
>                         >> adjustArguments(arguments.clone(),
>                         Integer.TYPE)) if _ != null
>                         >>
>                         >>     throw new
>                         GroovyRuntimeException("$methodName not
>                         found") } ```
>                         >>
>                         >>
>                         >> Cheers,
>                         >> Daniel Sun
>                         >> On 2020/07/26 17:11:07, MG
>                         <mg...@arscreat.com
>                         <mailto:mg...@arscreat.com>> wrote:
>                         >>> Hi Daniel,
>                         >>>
>                         >>> currently I would be +/- 0 on this.
>                         >>>
>                         >>> Thoughts:
>                         >>>
>                         >>>   1. I feel I have written this before,
>                         but I myself do not encounter the
>                         >>>      situation where I would need to
>                         return the result of a method call
>                         >>>      only if it meets certain conditions
>                         when programming (maybe you can
>                         >>>      give some real life code where you
>                         encounter this on a regular basis ?).
>                         >>>   2. If I have more than one return, it
>                         typcially is an early out, which
>                         >>>      depends on the method's input
>                         parameters, not on the result of
>                         >>>      another method call.
>                         >>>   3. Since I do a lot of logging / log
>                         debugging, I typically assign the
>                         >>>      return value to a variable, so I can
>                         debug-log it before the one
>                         >>>      return of the method.
>                         >>>   4. In fact I have had to refactor code
>                         written by other people from
>                         >>>      multi-return methods to single
>                         return, to be able to track down bugs.
>                         >>>
>                         >>> So overall I am not sure one should enable
>                         people to make it easier
>                         >>> to write non-single-return methods ;-)
>                         >>>
>                         >>>
>                         >>> Purely syntax wise I would prefer
>                         >>> return?
>                         >>> for the simple case,
>                         >>>
>                         >>> and
>                         >>>
>                         >>> return <something> if <condition>
>                         >>> for the more complex one*.
>                         >>>
>                         >>> I find
>                         >>> return(<condition)  <something>
>                         >>> confusing on what is actually returned.
>                         >>>
>                         >>> Cheers,
>                         >>> mg
>                         >>>
>                         >>> *Though I wonder if people would not then
>                         expect this
>                         >>> if-postfix-syntax to also work for e.g.
>                         assignments and method calls...
>                         >>>
>                         >>>
>                         >>> On 26/07/2020 16:15, Daniel Sun wrote:
>                         >>>> 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
>                         <mailto: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://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpmd.github.io%2Flatest%2Fpmd_rules_java_codestyle.html%23onlyonereturn&amp;data=02%7C01%7Ceric.milles%40thomsonreuters.com%7C411c66fda05844d7429908d831bacc9d%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637314025668554080&amp;sdata=5m%2B5ejCWEicseaUp5wK0UDjHwpfMFht5ptjglZ9IWS4%3D&amp;reserved=0
>                         
> <https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpmd.github.io%2Flatest%2Fpmd_rules_java_codestyle.html%23onlyonereturn&data=02%7C01%7Ceric.milles%40thomsonreuters.com%7C9a342f22ade649706de008d83b11a879%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637324294328833279&sdata=skDXVMhl0kDKiV9R71exKAetvbEYHIHGUIM4t2LgKVc%3D&reserved=0>).
>                         >>>>> 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://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2
>                         
> <https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%252>
>                         >>>>>
>                         
> Fmedium.com%2Fncr-edinburgh%2Fearly-exit-c86d5f0698ba&amp;data=02
>                         >>>>> %7C01%7Ceric.milles%40thomsonreuters.com
>                         
> <https://nam02.safelinks.protection.outlook.com/?url=http%3A%2F%2F40thomsonreuters.com%2F&data=02%7C01%7Ceric.milles%40thomsonreuters.com%7C9a342f22ade649706de008d83b11a879%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637324294328843273&sdata=opZCVux5wCCSILyxoM0q8hOMB7R4Wbc4GBY473D4LSU%3D&reserved=0>%7C411c66fda05844d7429908
>                         >>>>>
>                         
> d831bacc9d%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637314025
>                         >>>>>
>                         
> 668554080&amp;sdata=q8VrgoQDeH85232oyMgQT8WwljNqoUjIc4cS7GGqH5I%3
>                         >>>>> D&amp;reserved=0)
>                         >>>>>
>                         >>>>> 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
>                         <mailto: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
>                         <mailto: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