groovy
  1. groovy
  2. GROOVY-2892

Unless / If expressions support

    Details

    • Type: Wish Wish
    • Status: Open Open
    • Priority: Minor Minor
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: 4.0
    • Component/s: syntax
    • Labels:
      None
    • Number of attachments :
      0

      Description

      I would love to see Groovy support right-side unless / if expressions like in Python or Ruby as they make the code often more readable.

      Here is a small example:

      doSomething() unless (x > 10)
      
      (...)
      
      triggerSomethingNasty() if (x < 10)
      

        Activity

        Hide
        blackdrag blackdrag added a comment -

        what we could have is

        unless(x>10){doSomething}

        which is more or less like an if with a negated condition. The other order is a bit problematic in Groovy because there is no execution style like that in all of groovy. That would mean adding a new idiom, which makes the language more complicated. What could be done, would maybe:

        {doSomething}.unless(x>10)

        which is not exactly like in Python, but I think that is good enough. For this solution a category could be used to see if it is good.

        Show
        blackdrag blackdrag added a comment - what we could have is unless(x>10){doSomething} which is more or less like an if with a negated condition. The other order is a bit problematic in Groovy because there is no execution style like that in all of groovy. That would mean adding a new idiom, which makes the language more complicated. What could be done, would maybe: {doSomething}.unless(x>10) which is not exactly like in Python, but I think that is good enough. For this solution a category could be used to see if it is good.
        Hide
        Julien Ponge added a comment -

        That could indeed be a solution.

        I understand that allowing the form I mentioned would require a change in the grammar. However I think that this would not require much changes. I am not familiar with the Groovy parser and the AST that it generates, but a naive solution would be to transform an AST such as:

                    r_conditional("unless")
                    /            \
              b=true_branch      c=condition
        

        to:

                    if (not c)
                    /
                    b
        
        Show
        Julien Ponge added a comment - That could indeed be a solution. I understand that allowing the form I mentioned would require a change in the grammar. However I think that this would not require much changes. I am not familiar with the Groovy parser and the AST that it generates, but a naive solution would be to transform an AST such as: r_conditional("unless") / \ b=true_branch c=condition to: if (not c) / b
        Hide
        blackdrag blackdrag added a comment -

        representing this in the AST is not the primary issue here. There are several idioms in Groovy and most of our grammar is based on different forms of method calls. For example

        if (b) {println foo}

        can be seen as a method call to the method "if" with two parameters that are "b" and the block "

        {println foo}

        ". When I now look at

        doSomething() unless (x > 10)

        then I see a method call "doSomething()" like before with the if, but what follows? I can't be a method call if multiple arguments, because of the () and because no block follows. So what is it then? The solution I showed is based on an expression consisting of

        {doSomething()}

        and a method called on the result of that expression. So in my view it does not fit the overall style used in Groovy and I am tempted to say no to this, if your example is the only usage of a whole new idiom.

        Show
        blackdrag blackdrag added a comment - representing this in the AST is not the primary issue here. There are several idioms in Groovy and most of our grammar is based on different forms of method calls. For example if (b) {println foo} can be seen as a method call to the method "if" with two parameters that are "b" and the block " {println foo} ". When I now look at doSomething() unless (x > 10) then I see a method call "doSomething()" like before with the if, but what follows? I can't be a method call if multiple arguments, because of the () and because no block follows. So what is it then? The solution I showed is based on an expression consisting of {doSomething()} and a method called on the result of that expression. So in my view it does not fit the overall style used in Groovy and I am tempted to say no to this, if your example is the only usage of a whole new idiom.
        Hide
        Paul King added a comment -

        If we bring back in the do ... while loop, we could potentially support:

        if (condition) { ... }
        unless (condition) { ... }
        do { ... } while (condition)
        do { ... } if (condition)
        do { ... } unless (condition)
        
        Show
        Paul King added a comment - If we bring back in the do ... while loop, we could potentially support: if (condition) { ... } unless (condition) { ... } do { ... } while (condition) do { ... } if (condition) do { ... } unless (condition)
        Hide
        Robert Fischer added a comment -

        I'd rather do

        {...}

        .unless(condition) – putting conditional methods onto closures would be pretty nifty, and keep with the Groovy feel.

        Show
        Robert Fischer added a comment - I'd rather do {...} .unless(condition) – putting conditional methods onto closures would be pretty nifty, and keep with the Groovy feel.
        Hide
        blackdrag blackdrag added a comment -

        Julien, I would suggest you raise the issue on the groovy-user list to see the reactions of others.

        Show
        blackdrag blackdrag added a comment - Julien, I would suggest you raise the issue on the groovy-user list to see the reactions of others.
        Hide
        Julien Ponge added a comment -

        Done. Let's see what people think about the idea

        Show
        Julien Ponge added a comment - Done. Let's see what people think about the idea
        Hide
        Luke Daley added a comment -

        +1000 for unless, except I think we should stick with pre statement rather post statement. To be clear...

        unless (x > 10) doSomething()

        if (x < 10) triggerSomethingNasty()

        I actually prefer the ruby/perl style of having the condition afterwards for single statement expressions, but since Groovy already supports having the condition before the statement I would advocate sticking with this.

        Show
        Luke Daley added a comment - +1000 for unless, except I think we should stick with pre statement rather post statement. To be clear... unless (x > 10) doSomething() if (x < 10) triggerSomethingNasty() I actually prefer the ruby/perl style of having the condition afterwards for single statement expressions, but since Groovy already supports having the condition before the statement I would advocate sticking with this.
        Hide
        Russel Winder added a comment -

        I think having conditions as right-hand side properties of an expression is awful – especially in a read left-to-right language. Just because Perl and Ruby do it doesn't make it good and desirable – Python doesn't have the structure as was originally stated.

        Show
        Russel Winder added a comment - I think having conditions as right-hand side properties of an expression is awful – especially in a read left-to-right language. Just because Perl and Ruby do it doesn't make it good and desirable – Python doesn't have the structure as was originally stated.
        Hide
        Julien Ponge added a comment -

        My mistake, Python indeed doesn't have those constructs.

        Show
        Julien Ponge added a comment - My mistake, Python indeed doesn't have those constructs.
        Hide
        Russel Winder added a comment -

        No problem, I just wanted to ensure no mistakes got turned into facts

        It seems the debate is lively and alive on the mailing list, so I guess the best bet is to wait for things to iterate to a conclusion there and then post a summary item here.

        Show
        Russel Winder added a comment - No problem, I just wanted to ensure no mistakes got turned into facts It seems the debate is lively and alive on the mailing list, so I guess the best bet is to wait for things to iterate to a conclusion there and then post a summary item here.
        Hide
        John Fletcher added a comment -

        What was the conclusion on the user list? If this is all too hard, why not just create a separate issue to add 'unless' and confine this issue to the idea of reverse-syntax.

        Show
        John Fletcher added a comment - What was the conclusion on the user list? If this is all too hard, why not just create a separate issue to add 'unless' and confine this issue to the idea of reverse-syntax.
        Hide
        Guillaume Laforge added a comment -

        The conclusion is that it's not a very natual style for Groovy to have that conditional after the statement.
        So we're not really fond of implementing this feature.
        We're keeping old feature requests open in our bug tracker though, hence why this issue is still open.

        Show
        Guillaume Laforge added a comment - The conclusion is that it's not a very natual style for Groovy to have that conditional after the statement. So we're not really fond of implementing this feature. We're keeping old feature requests open in our bug tracker though, hence why this issue is still open.

          People

          • Assignee:
            Unassigned
            Reporter:
            Julien Ponge
          • Votes:
            6 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

            • Created:
              Updated: