groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul King <pa...@asert.com.au>
Subject Re: [Poll] About supporting Java-like array
Date Sun, 29 Apr 2018 23:51:50 GMT
On Mon, Apr 30, 2018 at 9:10 AM, mg <mgbiz@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 <paulk@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 <mgbiz@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 <sunlan@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
>>>
>>
>>
>>
>
>

Mime
View raw message