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

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>
*Sent:* Friday, August 7, 2020 12:41 PM
*To:* dev@groovy.apache.org; Paul King <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%7C47e9eafa50324d20595008d83af90b06%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637324188604137339&sdata=NZeJHRw8WnVbMBlPMtJNBAQ3GIgkzx2d2JH%2FpdYihJ0%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%7C47e9eafa50324d20595008d83af90b06%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637324188604137339&sdata=fUiBY%2F%2F%2BbzeUKMslv4iGJJEa8MHLnS%2BAH%2BNwyhlqVhQ%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%7C47e9eafa50324d20595008d83af90b06%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637324188604147336&sdata=IvRo8uB78duVVpplmqp290RZA1oyX9TX2XVqg1Wo6R8%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%7C47e9eafa50324d20595008d83af90b06%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637324188604157330&sdata=vJ0EGtfV1DZaAmfH77soyzfRZTfWuYDXm0WRwqeTy1E%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