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