groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From MG <mg...@arscreat.com>
Subject Re: [Poll] About supporting Java-like array
Date Sun, 29 Apr 2018 21:17:17 GMT
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 
> <mailto: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
>     <https://github.com/apache/groovy/pull/691>
>     [2] http://groovy-lang.org/differences.html
>     <http://groovy-lang.org/differences.html>
>
>
>
>
>     --
>     Sent from:
>     http://groovy.329449.n5.nabble.com/Groovy-Users-f329450.html
>     <http://groovy.329449.n5.nabble.com/Groovy-Users-f329450.html>
>
>


Mime
View raw message