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 Mon, 30 Apr 2018 14:08:14 GMT
I suggested CodeNarc first partly because it would be a little bit of work
to add warnings - the Groovy compiler doesn't really have any at present.
Also, Groovy has tried to not be too opinionated. If you leave those
semicolons in, Groovy won't complain. Of course removing the semicolons is
its own reward! :-)

Cheers, Paul.

On Mon, Apr 30, 2018 at 10:30 PM, mg <mgbiz@arscreat.com> wrote:

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