Yes, but what about all the (hopefully many) people new to Groovy, who don't 
use CodeNarc ? How do you educate them about what is idiomatic Groovy 
?Especially in cases like this, where a completely equivalent Groovy 
alternative exists...

I imagine something along the line:
Warning: Using {...} Java style array literals is not idiomatic Groovy. To 
avoid confusion with Groovy closures, it is recommended to use the 
performance-identical Groovy [...] list literal syntax instead.
I think we should decide if that is something we want to do in general, or not. 
My argument for it is, to avoid Groovy becoming a Babylonian-syntax-language 
like e.g. Ruby...
Cheers,mg




-------- Ursprüngliche Nachricht --------Von: Paul King <pa...@asert.com.au> 
Datum: 30.04.18  01:51  (GMT+01:00) An: users@groovy.apache.org Betreff: Re: 
[Poll] About supporting Java-like array 


On Mon, Apr 30, 2018 at 9:10 AM, mg <mg...@arscreat.com> wrote:
I would propose the Groovy compiler issue a warning to change the array 
initialization from Java- to Groovy-style then...

A codenarc rule would be a great first option. Cheers,mg


-------- Ursprüngliche Nachricht --------Von: Paul King <pa...@asert.com.au> 
Datum: 30.04.18  00:29  (GMT+01:00) An: users@groovy.apache.org Betreff: Re: 
[Poll] About supporting Java-like array 
The preferred Groovy syntax would probably still remain:

int[] fibs = [1, 1, 2, 3, 5, 8]

Cheers, Paul.
On Mon, Apr 30, 2018 at 7:17 AM, MG <mg...@arscreat.com> wrote:

  
    
  
  
    After thinking about this some more for the last weeks

    +1 with asterisk

    from my side:

    

    1) I am always for being as Java compatible as possible (though I
    see that this might not be feasible in all cases in the future, due
    to Java changing at a much faster pace and with more syntax changes
    now than before; example: Java considered naming the new "var"
    keword "def", which is similar to but not the same as Java-var in
    Groovy...) 

    

    2) I feel  { { } } being interpreted as an array containing an empty
    closure is confusing, i.e. not least surprise. I would rather not
    see it cut it so close with regards to what the Parrot parser can
    handle syntax-wise. What do others think ?

    

    3) After introducing this syntax extension, what will be considered
    the "Groovy way" of initializing an array in the future ? Is it
    still 

    final int[] a = [ 1, 1, 2, 3, 5, 8 ] as int[]

    or

    final int[] a = { 1, 1, 2, 3, 5, 8 }

    ?

    In the 2nd case I would be worried that the core Groovy syntax
    becomes all over the place over time, same as with the new Java
    lambda syntax (though less pronounced, since using/initializing
    arrays is typically rare).

    

    4) I am not too worried about the breaking edge cases, because I
    feel they are quite rare in practice, the compiler catches them, and
    they are easy to fix.

    

    Cheers,

    mg

    

    

    

    On 29.04.2018 15:29, Paul King wrote:

    
    
      +1
        

        
        For completeness, I added some more details about the
          breaking changes and workarounds into the issue - included
          below for easy reading.
        

        
        Cheers, Paul.
        

        
        =================
        

        
        
          Groovy currently "promotes" a singleton instance of an
            object into an array for assignments, e.g.:
          

          
          Integer[] nums = 42
          assert nums instanceof Integer[]
          assert nums.size() == 1
          assert nums[0] instanceof Integer
          

          
          This aligns with how Groovy behaves if you try to call
            `.each{}` on a non-aggregate. It treats it like a singleton
            collection and "iterates" over the one item.
          

          
          The existing behavior also currently works for singleton
            Closures:
          

          
          Closure[] fns0 = { }
          assert fns0 instanceof Closure[]
          assert fns0.size() == 1
          assert fns0[0] instanceof Closure
          

          
          To add support for Java array notation, we will need to
            partially disable this behavior. The proposed change
            involves smart parsing, e.g. it will distinguish cases which
            must be an array and cases which must be a closure but there
            are some degenerate edge cases which will become breaking
            changes.
          

          
          The case with the empty closure above will no longer
            work, instead you will get this behavior, i.e. an empty
            array is given precedence over an empty closure:
          

          
          Closure[] fns1 = { }
          assert fns1 instanceof Closure[]
          assert fns1.size() == 0
          

          
          To get the old behavior back you have a couple of
            options. Firstly, you can provide the explicit closure
            argument delimiter:
          

          
          Closure[] fns2 = { -> } // can't be an array
          assert fns2 instanceof Closure[]
          assert fns2.size() == 1
          assert fns2[0] instanceof Closure
          

          
          Or don't rely on singleton promotion and explicitly
            provide also the array curly braces:
          

          
          Closure[] fns3 = { { } }
          assert fns3 instanceof Closure[]
          assert fns3.size() == 1
          assert fns3[0] instanceof Closure
          

          
          Similarly, for the case of the identity closure:
          

          
          Closure[] fns4 = { it }
          

          
          Previously this worked but under this proposal will give:
          

          
          groovy.lang.MissingPropertyException: No such property:
            it ...
          

          
          Your options are to add the extra array braces as per
            above, or use explicit params, e.g.:
          

          
          Closure[] fns5 = { it -> it }
          assert fns5 instanceof Closure[]
          assert fns5.size() == 1
          assert fns5[0] instanceof Closure
          

          
          Alternatively, for this special case you have the
            following additional option:
          

          
          Closure[] fns6 = Closure.IDENTITY
          assert fns6 instanceof Closure[]
          assert fns6.size() == 1
          assert fns6[0] instanceof Closure
          

          
          There are other cases as well, e.g. this code which
            currently creates a closure array containing a closure
            returning the integer 0:
          

          
          Closure[] fns7 = { 0 }
          

          
          will no longer be supported and will fail with:
          

          
          org.codehaus.groovy.runtime.typehandling.GroovyCastException:
            Cannot cast object '0' with class 'java.lang.Integer' to
            class 'groovy.lang.Closure'
          The solutions are similar to previously (explicit
            delimiter):
          

          
          Closure[] fns8 = { -> 0 }
          

          
          or (explicit outer array braces):
          

          
          Closure[] fns9 = { { 0 } }
        
        

        
      
      

        On Sun, Apr 29, 2018 at 8:37 PM,
          Daniel.Sun <sun...@apache.org>
          wrote:

          Hi all,

            

                 As we all know, Java array is one of features widely
            applied in Java

            projects. In order to improve the compatibility with
            Java(Copy & Paste). The

            PR[1] will make Groovy support java-like array and make the
            differences[2]

            with Java less and less, e.g.

            

            *One-Dimensional array*

            ```

            String[] names = {'Jochen', 'Paul', 'Daniel'}

            ```

            

            *Two-Dimensional array*

            ```

            int[][] data = {

                {1, 2, 3},

                {4, 5, 6},

                {7, 8, 9},

                new int[] { 10, 11, 12 },

                {13, 14, 15}

            }

            ```

            

            *Annotation array*

            ```

            @PropertySources({

                @PropertySource("classpath:1.properties"),

                @PropertySource("file:2.properties")

            })

            public class Controller {}

            ```

            

            *More examples*

            Please see the examples on the PR page[1]

            

            *Known breaking changes*

            1. Closure array in the dynamic mode

            Before

            ```

            Closure[] y = { {-> 1 + 1 } }

            assert y[0].call().call() == 2

            ```

            After

            ```

            Closure[] y = { {-> 1 + 1 } }

            assert y[0].call() == 2

            ```

            2. String array in the dynamic mode

            Before

            ```

            String[] a = {}

            assert 1 == a.length

            assert a[0].contains('closure')

            ```

            After

            ```

            String[] a = {}

            assert 0 == a.length

            ```

            

            

                  If Groovy 3 supports Java-like array, what do you
            think about the new

            feature? Do you like it? We need your feedback. Thanks in
            advance!

            

            [+1] I like it

            [ 0] Not bad

            [-1] I don't like it, because...

            

            Cheers,

            Daniel.Sun

            [1] https://github.com/apache/groovy/pull/691

            [2] http://groovy-lang.org/differences.html

            

            

            

            

            --

            Sent from: 
http://groovy.329449.n5.nabble.com/Groovy-Users-f329450.html

          
        
        

      
    
    

  






Reply via email to