From users-return-3470-archive-asf-public=cust-asf.ponee.io@groovy.apache.org Mon Apr 30 01:39:50 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id A7EA918063A for ; Mon, 30 Apr 2018 01:39:49 +0200 (CEST) Received: (qmail 92399 invoked by uid 500); 29 Apr 2018 23:39:48 -0000 Mailing-List: contact users-help@groovy.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@groovy.apache.org Delivered-To: mailing list users@groovy.apache.org Received: (qmail 92389 invoked by uid 99); 29 Apr 2018 23:39:48 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd1-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 29 Apr 2018 23:39:48 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd1-us-west.apache.org (ASF Mail Server at spamd1-us-west.apache.org) with ESMTP id 25D7BCBCC3 for ; Sun, 29 Apr 2018 23:39:48 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 4.313 X-Spam-Level: **** X-Spam-Status: No, score=4.313 tagged_above=-999 required=6.31 tests=[HTML_MESSAGE=2, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_NONE=-0.0001, URI_HEX=1.313] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd1-us-west.apache.org [10.40.0.7]) (amavisd-new, port 10024) with ESMTP id X89g3AQN1mSE for ; Sun, 29 Apr 2018 23:39:45 +0000 (UTC) Received: from homiemail-a79.g.dreamhost.com (sub5.mail.dreamhost.com [208.113.200.129]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with ESMTPS id 4CFAE5F2AA for ; Sun, 29 Apr 2018 23:39:45 +0000 (UTC) Received: from homiemail-a79.g.dreamhost.com (localhost [127.0.0.1]) by homiemail-a79.g.dreamhost.com (Postfix) with ESMTP id 69E8A6007F12 for ; Sun, 29 Apr 2018 16:39:38 -0700 (PDT) Received: from [192.168.1.10] (pool-96-248-39-38.pghkny.fios.verizon.net [96.248.39.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: keith@suderman.com) by homiemail-a79.g.dreamhost.com (Postfix) with ESMTPSA id 0F2F86007F10 for ; Sun, 29 Apr 2018 16:39:37 -0700 (PDT) From: Keith Suderman Content-Type: multipart/alternative; boundary="Apple-Mail=_BE2219F5-8E5A-4DB0-9034-3897872323DC" Mime-Version: 1.0 (Mac OS X Mail 11.3 \(3445.6.18\)) Subject: Re: [Poll] About supporting Java-like array Date: Sun, 29 Apr 2018 19:39:36 -0400 References: <20180429231029.C894E4FE@mail.cs.vassar.edu> To: users@groovy.apache.org In-Reply-To: <20180429231029.C894E4FE@mail.cs.vassar.edu> Message-Id: <53923483-686F-45AD-8191-1FEB12ABB6BF@anc.org> X-Mailer: Apple Mail (2.3445.6.18) --Apple-Mail=_BE2219F5-8E5A-4DB0-9034-3897872323DC Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Apr 29, 2018, at 7:10 PM, mg wrote: >=20 > Well tickle my belly and colour me green - I always thought using the = "as" form was mandatory here (based on the examples I saw on the net = back then) :-) Yep me too. Learn something new every day ;)=20 - Keith >=20 > That means this is the one case where giving an explicit type is the = most concise way to get what you want ;-) >=20 > I would propose the Groovy compiler issue a warning to change the = array initialization from Java- to Groovy-style then... > Cheers, > mg >=20 >=20 >=20 > -------- Urspr=C3=BCngliche Nachricht -------- > Von: Paul King > Datum: 30.04.18 00:29 (GMT+01:00) > An: users@groovy.apache.org > Betreff: Re: [Poll] About supporting Java-like array >=20 > The preferred Groovy syntax would probably still remain: >=20 > int[] fibs =3D [1, 1, 2, 3, 5, 8] >=20 > Cheers, Paul. >=20 > On Mon, Apr 30, 2018 at 7:17 AM, MG > wrote: > After thinking about this some more for the last weeks > +1 with asterisk > from my side: >=20 > 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...)=20 >=20 > 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 ? >=20 > 3) After introducing this syntax extension, what will be considered = the "Groovy way" of initializing an array in the future ? Is it still=20 > final int[] a =3D [ 1, 1, 2, 3, 5, 8 ] as int[] > or > final int[] a =3D { 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). >=20 > 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. >=20 > Cheers, > mg >=20 >=20 >=20 >=20 > On 29.04.2018 15:29, Paul King wrote: >> +1 >>=20 >> For completeness, I added some more details about the breaking = changes and workarounds into the issue - included below for easy = reading. >>=20 >> Cheers, Paul. >>=20 >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >>=20 >> Groovy currently "promotes" a singleton instance of an object into an = array for assignments, e.g.: >>=20 >> Integer[] nums =3D 42 >> assert nums instanceof Integer[] >> assert nums.size() =3D=3D 1 >> assert nums[0] instanceof Integer >>=20 >> 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. >>=20 >> The existing behavior also currently works for singleton Closures: >>=20 >> Closure[] fns0 =3D { } >> assert fns0 instanceof Closure[] >> assert fns0.size() =3D=3D 1 >> assert fns0[0] instanceof Closure >>=20 >> 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. >>=20 >> 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: >>=20 >> Closure[] fns1 =3D { } >> assert fns1 instanceof Closure[] >> assert fns1.size() =3D=3D 0 >>=20 >> To get the old behavior back you have a couple of options. Firstly, = you can provide the explicit closure argument delimiter: >>=20 >> Closure[] fns2 =3D { -> } // can't be an array >> assert fns2 instanceof Closure[] >> assert fns2.size() =3D=3D 1 >> assert fns2[0] instanceof Closure >>=20 >> Or don't rely on singleton promotion and explicitly provide also the = array curly braces: >>=20 >> Closure[] fns3 =3D { { } } >> assert fns3 instanceof Closure[] >> assert fns3.size() =3D=3D 1 >> assert fns3[0] instanceof Closure >>=20 >> Similarly, for the case of the identity closure: >>=20 >> Closure[] fns4 =3D { it } >>=20 >> Previously this worked but under this proposal will give: >>=20 >> groovy.lang.MissingPropertyException: No such property: it ... >>=20 >> Your options are to add the extra array braces as per above, or use = explicit params, e.g.: >>=20 >> Closure[] fns5 =3D { it -> it } >> assert fns5 instanceof Closure[] >> assert fns5.size() =3D=3D 1 >> assert fns5[0] instanceof Closure >>=20 >> Alternatively, for this special case you have the following = additional option: >>=20 >> Closure[] fns6 =3D Closure.IDENTITY >> assert fns6 instanceof Closure[] >> assert fns6.size() =3D=3D 1 >> assert fns6[0] instanceof Closure >>=20 >> There are other cases as well, e.g. this code which currently creates = a closure array containing a closure returning the integer 0: >>=20 >> Closure[] fns7 =3D { 0 } >>=20 >> will no longer be supported and will fail with: >>=20 >> 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): >>=20 >> Closure[] fns8 =3D { -> 0 } >>=20 >> or (explicit outer array braces): >>=20 >> Closure[] fns9 =3D { { 0 } } >>=20 >>=20 >> On Sun, Apr 29, 2018 at 8:37 PM, Daniel.Sun > wrote: >> Hi all, >>=20 >> 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. >>=20 >> *One-Dimensional array* >> ``` >> String[] names =3D {'Jochen', 'Paul', 'Daniel'} >> ``` >>=20 >> *Two-Dimensional array* >> ``` >> int[][] data =3D { >> {1, 2, 3}, >> {4, 5, 6}, >> {7, 8, 9}, >> new int[] { 10, 11, 12 }, >> {13, 14, 15} >> } >> ``` >>=20 >> *Annotation array* >> ``` >> @PropertySources({ >> @PropertySource("classpath:1.properties"), >> @PropertySource("file:2 <>.properties") >> }) >> public class Controller {} >> ``` >>=20 >> *More examples* >> Please see the examples on the PR page[1] >>=20 >> *Known breaking changes* >> 1. Closure array in the dynamic mode >> Before >> ``` >> Closure[] y =3D { {-> 1 + 1 } } >> assert y[0].call().call() =3D=3D 2 >> ``` >> After >> ``` >> Closure[] y =3D { {-> 1 + 1 } } >> assert y[0].call() =3D=3D 2 >> ``` >> 2. String array in the dynamic mode >> Before >> ``` >> String[] a =3D {} >> assert 1 =3D=3D a.length >> assert a[0].contains('closure') >> ``` >> After >> ``` >> String[] a =3D {} >> assert 0 =3D=3D a.length >> ``` >>=20 >>=20 >> 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! >>=20 >> [+1] I like it >> [ 0] Not bad >> [-1] I don't like it, because... >>=20 >> Cheers, >> Daniel.Sun >> [1] https://github.com/apache/groovy/pull/691 = >> [2] http://groovy-lang.org/differences.html = >>=20 >>=20 >>=20 >>=20 >> -- >> Sent from: = http://groovy.329449.n5.nabble.com/Groovy-Users-f329450.html = >>=20 >=20 >=20 ---------------------- Keith Suderman Research Associate Department of Computer Science Vassar College, Poughkeepsie NY suderman@cs.vassar.edu --Apple-Mail=_BE2219F5-8E5A-4DB0-9034-3897872323DC Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8

On Apr 29, 2018, at 7:10 PM, mg <mgbiz@arscreat.com> = wrote:

Well tickle my belly and colour me green - I = always thought using the "as" form was mandatory here (based on the = examples I saw on the net back then) = :-)

Yep me too. Learn = something new every day ;) 

- = Keith


That means this is the one case where = giving an explicit type is the most concise way to get what you want = ;-)

I would = propose the Groovy compiler issue a warning to change the array = initialization from Java- to Groovy-style then...
Cheers,
mg



-------- Urspr=C3=BCngliche Nachricht = --------
Von: Paul King <paulk@asert.com.au> =
Datum: 30.04.18 00:29 (GMT+01:00)
Betreff: = Re: [Poll] About supporting Java-like array

The preferred Groovy = syntax would probably still remain:

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

Cheers, Paul.

On Mon, Apr 30, 2018 at 7:17 AM, = MG <mgbiz@arscreat.com> wrote:
=20 =20 =20
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 =3D [ 1, 1, 2, 3, 5, 8 ] as int[]
or
final int[] a =3D { 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.

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

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

Integer[] nums =3D 42
assert nums instanceof Integer[]
assert nums.size() =3D=3D 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 =3D { }
assert fns0 instanceof Closure[]
assert fns0.size() =3D=3D 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 =3D { }
assert fns1 instanceof Closure[]
assert fns1.size() =3D=3D 0

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

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

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

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

Similarly, for the case of the identity = closure:

Closure[] fns4 =3D { 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 =3D { it -> it }
assert fns5 instanceof Closure[]
assert fns5.size() =3D=3D 1
assert fns5[0] instanceof Closure

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

Closure[] fns6 =3D Closure.IDENTITY
assert fns6 instanceof Closure[]
assert fns6.size() =3D=3D 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 =3D { 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 =3D { -> 0 }

or (explicit outer array braces):

Closure[] fns9 =3D { { 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 =3D {'Jochen', 'Paul', 'Daniel'}
= ```

*Two-Dimensional array*
```
int[][] data =3D {
    {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 =3D { {-> 1 + 1 } }
assert y[0].call().call() =3D=3D 2
```
After
```
Closure[] y =3D { {-> 1 + 1 } }
assert y[0].call() =3D=3D 2
```
2. String array in the dynamic mode
Before
```
String[] a =3D {}
assert 1 =3D=3D a.length
assert a[0].contains('closure')
```
After
```
String[] a =3D {}
assert 0 =3D=3D 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




----------------------
Keith = Suderman
Research Associate
Department of Computer = Science
Vassar = College, Poughkeepsie NY




= --Apple-Mail=_BE2219F5-8E5A-4DB0-9034-3897872323DC--