You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@groovy.apache.org by Paul King <pa...@asert.com.au> on 2018/09/03 22:30:50 UTC

Constructor call short-hand syntax

Groovy has a rarely used shorthand syntax for constructors:

println Date[time:0] // same as new Date(time:0)
println Date[year: 118, month: 8, date: 3] // same as new Date(year: 118,
month: 8, date: 3)


   1. GROOVY-8602 <https://issues.apache.org/jira/browse/GROOVY-8602>points
   out that the safe args version isn't supported, e.g.:

   println Date?[time:0]

   I was thinking of closing this as won't fix since we only support this
   shorthand for class constants.

   Any objections?

   Also, I noticed that the empty map isn't catered for:

   println Date[:] // as per above, might be expected to be the same as new
   Date([:]) or new Date()

// currently NPE: Cannot get property '{}' on null object

So, the map isn't found and the expression becomes "println Date" which
returns void and then we convert the map to a String and look for that
property.

I realise this is a weird edge case but I was thinking of creating an issue
to fix this for consistency (just Groovy 3). We already support this:

def map = [:]
println Date[*:map]

Let me know if you have other thoughts.


Cheers, Paul.

Re: Constructor call short-hand syntax

Posted by Paul King <pa...@asert.com.au>.
On Wed, Sep 5, 2018 at 3:24 AM Daniil Ovchinnikov <
daniil.ovchinnikov@jetbrains.com> wrote:

> Same as someObject?.getAt(x:y)
>

That would be the right mapping but we don't have any getAt(Map) support at
the moment - well apart from the ClassConstant constructor short-hand being
discussed..


>
>
> On 4 Sep 2018, at 20:23, Daniel.Sun <su...@apache.org> wrote:
>
> OK. I wonder what semantic `somMap?[x:y]` should be @_@
>
> Cheers,
> Daniel.Sun
>
>
>
>
> -----
> Daniel Sun
> Apache Groovy committer
> Blog: http://blog.sunlan.me
> Twitter: @daniel_sun
>
> --
> Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
>
>
>

Re: Constructor call short-hand syntax

Posted by Daniil Ovchinnikov <da...@jetbrains.com>.
Same as someObject?.getAt(x:y)
—

Daniil Ovchinnikov
JetBrains


> On 4 Sep 2018, at 20:23, Daniel.Sun <su...@apache.org> wrote:
> 
> OK. I wonder what semantic `somMap?[x:y]` should be @_@
> 
> Cheers,
> Daniel.Sun
> 
> 
> 
> 
> -----
> Daniel Sun 
> Apache Groovy committer 
> Blog: http://blog.sunlan.me 
> Twitter: @daniel_sun 
> 
> --
> Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html


Re: Constructor call short-hand syntax

Posted by "Daniel.Sun" <su...@apache.org>.
OK. I wonder what semantic `somMap?[x:y]` should be @_@

Cheers,
Daniel.Sun




-----
Daniel Sun 
Apache Groovy committer 
Blog: http://blog.sunlan.me 
Twitter: @daniel_sun 

--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html

Re: Constructor call short-hand syntax

Posted by "Milles, Eric (TR Technology & Ops)" <er...@thomsonreuters.com>.
I checked a couple quick examples and the AST represents these as CastExpressions, not ConstructorCallExpressions.  That may help shed some light on the case for @Newify which inserts actual CCEs into the AST.


date = Date[year: 1990] // cast
date = (Date) [year: 1990] // cast
date = [year: 1990] as Date // cast/coerce
date = new Date(year: 1990) // constructor call


With that in mind, I think that "Date[:]" should work exactly the same as "(Date) [:]" and "[:] as Date" work.

________________________________
From: mg <mg...@arscreat.com>
Sent: Wednesday, September 5, 2018 9:21 AM
To: dev@groovy.apache.org
Subject: Re: Constructor call short-hand syntax

PS: I would love to get rid of @Newify and have Groovy simply support class instance creation with and without new keyword (maybe only for classes whose name starts with an uppercase letter, for performance reasons), same as eg Python or Jetbrain's Kotlin does.

@Newify is a compromise, and I am happy that we do now have the pattern parameter. Btw, do we have an eta for IntelliJ @Newify(pattern=...) support ?-)

-------- Ursprüngliche Nachricht --------
Von: Daniil Ovchinnikov <da...@jetbrains.com>
Datum: 05.09.18 14:54 (GMT+01:00)
An: dev@groovy.apache.org
Betreff: Re: Constructor call short-hand syntax

I didn’t know that it’s a shorthand constructor syntax when I’ve created a ticket.

I thought it should just work as shorthand for getAt call:
a[1, 2] == a.getAt(1, 2)
a[x: y] == a.getAt(x: y)
a?[1, 2] == a?.getAt(1, 2) // this works already
a?[x: y] == a?.getAt(x: y)

And now I see it as a perfect Groovy-style replacement for @Newify.

Why even @Newify exists if Groovy already had Person[name: “John”, age: 42] syntax?
If such syntax exists, why not extend it to be equivalent to Person.class.getAt(name: “John”, age: 42), where getAt on a class instance would instantiate a new object ?
The last question implies that getAt would work with any arguments, including named ones.

—

Daniil Ovchinnikov
JetBrains


On 5 Sep 2018, at 01:22, Paul King <pa...@asert.com.au>> wrote:



On Wed, Sep 5, 2018 at 2:52 AM Jochen Theodorou <bl...@gmx.org>> wrote:
Am 04.09.2018 um 06:49 schrieb Daniel Sun:
> Hi Paul,
>
>       Safe index is only for accessing the elements of collections and object
> properties, but not for creating instance. The collections and objects may
> be null, so we designed the "safe" index.
>
>       To sum up, I vote -1 to support syntax like `Date[time:0]`, the class
> instance will not be null.

I think you actually miss the point a little. Let me rephrase... should
we support

somMap?[x:y]

for example. I personally think we can take supporting things like
x[y:z] and x?[y:z] as future project... if we find a nice use case for this.

We certainly could ... but we don't have such a proposal in front of us right now, so it's
whether we'd like to cater for the current situation in the meantime with an improved
error message. We could remove such an error message at a future point if we have
an acceptable proposal.

Having said that, it's hard to pick up this error case here without also making the
missing : within a ternary error message look more complex. You'd basically need
an error message that coped with both cases. Hence my suggestion to close as
"Won't fix". (But fix up the empty Map edge case only - without safe decorator).

bye Jochen


Re: Constructor call short-hand syntax

Posted by mg <mg...@arscreat.com>.
In my view creating a new instance of a class is a call to its ctor, which takes arguments, for which the (shorthand) syntax in Java and Groovy is (...), not [...]
[...] is access by indices / get something at coordinates. Even if one would follow the view that a Class object contains an infinite amount of instances inside of it, which are accessed through class' ctor parameters interpreted as indices, then [...] semantics would still imply that each access with the same index tuple (ie parameters) will return the same class instance - which is evidently not compatible with ctor calls.
(This is in addition to the fact that you cannot discontinue the syntactically very different looking mainstream, existing new Goo(...) syntax since it a) is what Java (and other) devs know, b) it is in every Groovy program/script ever written, and c) it is in DSLs.)
Cheers,mg

-------- Ursprüngliche Nachricht --------Von: Daniil Ovchinnikov <da...@jetbrains.com> Datum: 05.09.18  14:54  (GMT+01:00) An: dev@groovy.apache.org Betreff: Re: Constructor call short-hand syntax 
I didn’t know that it’s a shorthand constructor syntax when I’ve created a ticket. 
I thought it should just work as shorthand for getAt call:a[1, 2] == a.getAt(1, 2)a[x: y] == a.getAt(x: y)a?[1, 2] == a?.getAt(1, 2) // this works alreadya?[x: y] == a?.getAt(x: y)
And now I see it as a perfect Groovy-style replacement for @Newify.
Why even @Newify exists if Groovy already had Person[name: “John”, age: 42] syntax?If such syntax exists, why not extend it to be equivalent to Person.class.getAt(name: “John”, age: 42), where getAt on a class instance would instantiate a new object ?The last question implies that getAt would work with any arguments, including named ones.

—

Daniil Ovchinnikov
JetBrains




On 5 Sep 2018, at 01:22, Paul King <pa...@asert.com.au> wrote:


On Wed, Sep 5, 2018 at 2:52 AM Jochen Theodorou <bl...@gmx.org> wrote:Am 04.09.2018 um 06:49 schrieb Daniel Sun:
> Hi Paul,
> 
>       Safe index is only for accessing the elements of collections and object
> properties, but not for creating instance. The collections and objects may
> be null, so we designed the "safe" index.
> 
>       To sum up, I vote -1 to support syntax like `Date[time:0]`, the class
> instance will not be null.

I think you actually miss the point a little. Let me rephrase... should 
we support

somMap?[x:y]

for example. I personally think we can take supporting things like 
x[y:z] and x?[y:z] as future project... if we find a nice use case for this.

We certainly could ... but we don't have such a proposal in front of us right now, so it'swhether we'd like to cater for the current situation in the meantime with an improvederror message. We could remove such an error message at a future point if we havean acceptable proposal.
Having said that, it's hard to pick up this error case here without also making themissing : within a ternary error message look more complex. You'd basically needan error message that coped with both cases. Hence my suggestion to close as"Won't fix". (But fix up the empty Map edge case only - without safe decorator).
bye Jochen

Re: Constructor call short-hand syntax

Posted by mg <mg...@arscreat.com>.
PS: I would love to get rid of @Newify and have Groovy simply support class instance creation with and without new keyword (maybe only for classes whose name starts with an uppercase letter, for performance reasons), same as eg Python or Jetbrain's Kotlin does. 
@Newify is a compromise, and I am happy that we do now have the pattern parameter. Btw, do we have an eta for IntelliJ @Newify(pattern=...) support ?-)
-------- Ursprüngliche Nachricht --------Von: Daniil Ovchinnikov <da...@jetbrains.com> Datum: 05.09.18  14:54  (GMT+01:00) An: dev@groovy.apache.org Betreff: Re: Constructor call short-hand syntax 
I didn’t know that it’s a shorthand constructor syntax when I’ve created a ticket. 
I thought it should just work as shorthand for getAt call:a[1, 2] == a.getAt(1, 2)a[x: y] == a.getAt(x: y)a?[1, 2] == a?.getAt(1, 2) // this works alreadya?[x: y] == a?.getAt(x: y)
And now I see it as a perfect Groovy-style replacement for @Newify.
Why even @Newify exists if Groovy already had Person[name: “John”, age: 42] syntax?If such syntax exists, why not extend it to be equivalent to Person.class.getAt(name: “John”, age: 42), where getAt on a class instance would instantiate a new object ?The last question implies that getAt would work with any arguments, including named ones.

—

Daniil Ovchinnikov
JetBrains




On 5 Sep 2018, at 01:22, Paul King <pa...@asert.com.au> wrote:


On Wed, Sep 5, 2018 at 2:52 AM Jochen Theodorou <bl...@gmx.org> wrote:Am 04.09.2018 um 06:49 schrieb Daniel Sun:
> Hi Paul,
> 
>       Safe index is only for accessing the elements of collections and object
> properties, but not for creating instance. The collections and objects may
> be null, so we designed the "safe" index.
> 
>       To sum up, I vote -1 to support syntax like `Date[time:0]`, the class
> instance will not be null.

I think you actually miss the point a little. Let me rephrase... should 
we support

somMap?[x:y]

for example. I personally think we can take supporting things like 
x[y:z] and x?[y:z] as future project... if we find a nice use case for this.

We certainly could ... but we don't have such a proposal in front of us right now, so it'swhether we'd like to cater for the current situation in the meantime with an improvederror message. We could remove such an error message at a future point if we havean acceptable proposal.
Having said that, it's hard to pick up this error case here without also making themissing : within a ternary error message look more complex. You'd basically needan error message that coped with both cases. Hence my suggestion to close as"Won't fix". (But fix up the empty Map edge case only - without safe decorator).
bye Jochen

Re: Constructor call short-hand syntax

Posted by Daniil Ovchinnikov <da...@jetbrains.com>.
I didn’t know that it’s a shorthand constructor syntax when I’ve created a ticket. 

I thought it should just work as shorthand for getAt call:
a[1, 2] == a.getAt(1, 2)
a[x: y] == a.getAt(x: y)
a?[1, 2] == a?.getAt(1, 2) // this works already
a?[x: y] == a?.getAt(x: y)

And now I see it as a perfect Groovy-style replacement for @Newify.

Why even @Newify exists if Groovy already had Person[name: “John”, age: 42] syntax?
If such syntax exists, why not extend it to be equivalent to Person.class.getAt(name: “John”, age: 42), where getAt on a class instance would instantiate a new object ?
The last question implies that getAt would work with any arguments, including named ones.

—

Daniil Ovchinnikov
JetBrains


> On 5 Sep 2018, at 01:22, Paul King <pa...@asert.com.au> wrote:
> 
> 
> 
> On Wed, Sep 5, 2018 at 2:52 AM Jochen Theodorou <blackdrag@gmx.org <ma...@gmx.org>> wrote:
> Am 04.09.2018 um 06:49 schrieb Daniel Sun:
> > Hi Paul,
> > 
> >       Safe index is only for accessing the elements of collections and object
> > properties, but not for creating instance. The collections and objects may
> > be null, so we designed the "safe" index.
> > 
> >       To sum up, I vote -1 to support syntax like `Date[time:0]`, the class
> > instance will not be null.
> 
> I think you actually miss the point a little. Let me rephrase... should 
> we support
> 
> somMap?[x:y]
> 
> for example. I personally think we can take supporting things like 
> x[y:z] and x?[y:z] as future project... if we find a nice use case for this.
> 
> We certainly could ... but we don't have such a proposal in front of us right now, so it's
> whether we'd like to cater for the current situation in the meantime with an improved
> error message. We could remove such an error message at a future point if we have
> an acceptable proposal.
> 
> Having said that, it's hard to pick up this error case here without also making the
> missing : within a ternary error message look more complex. You'd basically need
> an error message that coped with both cases. Hence my suggestion to close as
> "Won't fix". (But fix up the empty Map edge case only - without safe decorator).
> 
> bye Jochen


Re: Constructor call short-hand syntax

Posted by Jochen Theodorou <bl...@gmx.org>.

Am 05.09.2018 um 00:22 schrieb Paul King:
[..]
>     for example. I personally think we can take supporting things like
>     x[y:z] and x?[y:z] as future project... if we find a nice use case
>     for this.
> 
> We certainly could ... but we don't have such a proposal in front of us 
> right now,

How about this... think of t as a sql database based table T and t[id:1] 
as a version to do "select * from T where id=1"

bye Jochen

Re: Constructor call short-hand syntax

Posted by Paul King <pa...@asert.com.au>.
On Wed, Sep 5, 2018 at 2:52 AM Jochen Theodorou <bl...@gmx.org> wrote:

> Am 04.09.2018 um 06:49 schrieb Daniel Sun:
> > Hi Paul,
> >
> >       Safe index is only for accessing the elements of collections and
> object
> > properties, but not for creating instance. The collections and objects
> may
> > be null, so we designed the "safe" index.
> >
> >       To sum up, I vote -1 to support syntax like `Date[time:0]`, the
> class
> > instance will not be null.
>
> I think you actually miss the point a little. Let me rephrase... should
> we support
>
> somMap?[x:y]
>
> for example. I personally think we can take supporting things like
> x[y:z] and x?[y:z] as future project... if we find a nice use case for
> this.
>

We certainly could ... but we don't have such a proposal in front of us
right now, so it's
whether we'd like to cater for the current situation in the meantime with
an improved
error message. We could remove such an error message at a future point if
we have
an acceptable proposal.

Having said that, it's hard to pick up this error case here without also
making the
missing : within a ternary error message look more complex. You'd basically
need
an error message that coped with both cases. Hence my suggestion to close as
"Won't fix". (But fix up the empty Map edge case only - without safe
decorator).

bye Jochen
>

Re: Constructor call short-hand syntax

Posted by Jochen Theodorou <bl...@gmx.org>.

Am 04.09.2018 um 06:49 schrieb Daniel Sun:
> Hi Paul,
> 
>       Safe index is only for accessing the elements of collections and object
> properties, but not for creating instance. The collections and objects may
> be null, so we designed the "safe" index.
> 
>       To sum up, I vote -1 to support syntax like `Date[time:0]`, the class
> instance will not be null.

I think you actually miss the point a little. Let me rephrase... should 
we support

somMap?[x:y]

for example. I personally think we can take supporting things like 
x[y:z] and x?[y:z] as future project... if we find a nice use case for this.

bye Jochen

Re: Constructor call short-hand syntax

Posted by "Daniel.Sun" <su...@apache.org>.
Yep. The safe index of `Date?[time:0]` looks pointless...

Cheers,
Daniel.Sun




-----
Daniel Sun 
Apache Groovy committer 
Blog: http://blog.sunlan.me 
Twitter: @daniel_sun 

--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html

Re: Constructor call short-hand syntax

Posted by Paul King <pa...@asert.com.au>.
Daniel,

Just to clarify, your vote for -1 is for `Date?[time:0]`. Right?


On Tue, Sep 4, 2018 at 2:49 PM Daniel Sun <re...@hotmail.com> wrote:

> Hi Paul,
>
>      Safe index is only for accessing the elements of collections and
> object
> properties, but not for creating instance. The collections and objects may
> be null, so we designed the "safe" index.
>
>      To sum up, I vote -1 to support syntax like `Date[time:0]`, the class
> instance will not be null.
>
> Cheers,
> Daniel.Sun
>
>
>
> --
> Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
>

Re: Constructor call short-hand syntax

Posted by Daniel Sun <re...@hotmail.com>.
Hi Paul,

     Safe index is only for accessing the elements of collections and object
properties, but not for creating instance. The collections and objects may
be null, so we designed the "safe" index.

     To sum up, I vote -1 to support syntax like `Date[time:0]`, the class
instance will not be null.

Cheers,
Daniel.Sun



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html

Re: Constructor call short-hand syntax

Posted by mg <mg...@arscreat.com>.
I think we should consider deprecating and/or hiding such syntax constructs behind a compiler switch / @Legacy annotation, otherwise we can never rid Groovy of sins from the past.
Short term in my opinion we should definitely "will not fix" GROOVY-8602, and leave the [:] edge case as is (ie unsupported), as to not encourage use of the syntax.

-------- Ursprüngliche Nachricht --------Von: Paul King <pa...@asert.com.au> Datum: 05.09.18  00:08  (GMT+01:00) An: dev@groovy.apache.org Betreff: Re: Constructor call short-hand syntax 


On Wed, Sep 5, 2018 at 4:58 AM mg <mg...@arscreat.com> wrote:
Couldn't we rather consider phasing out the whole construct ? Allowing a ctor to be called without new only in this special case seems awfully inconsistent...
I think it has been around for a long time and might be in use in DSLs. I'd probably not encourage it's use in normal programming but see no harm in leacing the existing support. And with the new @MapConstructor / @NamedVariant/... and @Newify(pattern=...) support, one can achieve the same thing from modular annotation building blocks - just without the confusing square brackets syntax (which does not work for method calls taking a map argument).
-------- Ursprüngliche Nachricht --------Von: Paul King <pa...@asert.com.au> Datum: 04.09.18  00:30  (GMT+01:00) An: dev@groovy.apache.org Betreff: Constructor call short-hand syntax 

Groovy has a rarely used shorthand syntax for constructors:
println Date[time:0] // same as new Date(time:0)println Date[year: 118, month: 8, date: 3] // same as new Date(year: 118, month: 8, date: 3)
GROOVY-8602points out that the safe args version isn't supported, e.g.:
println Date?[time:0]
I was thinking of closing this as won't fix since we only support this shorthand for class constants.
Any objections?
Also, I noticed that the empty map isn't catered for:
println Date[:] // as per above, might be expected to be the same as new Date([:]) or new Date()
// currently NPE: Cannot get property '{}' on null object
So, the map isn't found and the expression becomes "println Date" which returns void and then we convert the map to a String and look for that property.
I realise this is a weird edge case but I was thinking of creating an issue to fix this for consistency (just Groovy 3). We already support this:

def map = [:]println Date[*:map]
Let me know if you have other thoughts.

Cheers, Paul.



Re: Constructor call short-hand syntax

Posted by Paul King <pa...@asert.com.au>.
On Wed, Sep 5, 2018 at 4:58 AM mg <mg...@arscreat.com> wrote:

> Couldn't we rather consider phasing out the whole construct ? Allowing a
> ctor to be called without new only in this special case seems awfully
> inconsistent...
>

I think it has been around for a long time and might be in use in DSLs. I'd
probably not encourage it's use in normal programming but see no harm in
leacing the existing support.


> And with the new @MapConstructor / @NamedVariant/...
> and @Newify(pattern=...) support, one can achieve the same thing from
> modular annotation building blocks - just without the confusing square
> brackets syntax (which does not work for method calls taking a map
> argument).
>
> -------- Ursprüngliche Nachricht --------
> Von: Paul King <pa...@asert.com.au>
> Datum: 04.09.18 00:30 (GMT+01:00)
> An: dev@groovy.apache.org
> Betreff: Constructor call short-hand syntax
>
>
> Groovy has a rarely used shorthand syntax for constructors:
>
> println Date[time:0] // same as new Date(time:0)
> println Date[year: 118, month: 8, date: 3] // same as new Date(year: 118,
> month: 8, date: 3)
>
>
>    1. GROOVY-8602 <https://issues.apache.org/jira/browse/GROOVY-8602>points
>    out that the safe args version isn't supported, e.g.:
>
>    println Date?[time:0]
>
>    I was thinking of closing this as won't fix since we only support this
>    shorthand for class constants.
>
>    Any objections?
>
>    Also, I noticed that the empty map isn't catered for:
>
>    println Date[:] // as per above, might be expected to be the same as
>    new Date([:]) or new Date()
>
> // currently NPE: Cannot get property '{}' on null object
>
> So, the map isn't found and the expression becomes "println Date" which
> returns void and then we convert the map to a String and look for that
> property.
>
> I realise this is a weird edge case but I was thinking of creating an
> issue to fix this for consistency (just Groovy 3). We already support this:
>
> def map = [:]
> println Date[*:map]
>
> Let me know if you have other thoughts.
>
>
> Cheers, Paul.
>
>

Re: Constructor call short-hand syntax

Posted by mg <mg...@arscreat.com>.
Couldn't we rather consider phasing out the whole construct ? Allowing a ctor to be called without new only in this special case seems awfully inconsistent....
And with the new @MapConstructor / @NamedVariant/... and @Newify(pattern=...) support, one can achieve the same thing from modular annotation building blocks - just without the confusing square brackets syntax (which does not work for method calls taking a map argument).
-------- Ursprüngliche Nachricht --------Von: Paul King <pa...@asert.com.au> Datum: 04.09.18  00:30  (GMT+01:00) An: dev@groovy.apache.org Betreff: Constructor call short-hand syntax 

Groovy has a rarely used shorthand syntax for constructors:
println Date[time:0] // same as new Date(time:0)println Date[year: 118, month: 8, date: 3] // same as new Date(year: 118, month: 8, date: 3)
GROOVY-8602points out that the safe args version isn't supported, e.g.:
println Date?[time:0]
I was thinking of closing this as won't fix since we only support this shorthand for class constants.
Any objections?
Also, I noticed that the empty map isn't catered for:
println Date[:] // as per above, might be expected to be the same as new Date([:]) or new Date()
// currently NPE: Cannot get property '{}' on null object
So, the map isn't found and the expression becomes "println Date" which returns void and then we convert the map to a String and look for that property.
I realise this is a weird edge case but I was thinking of creating an issue to fix this for consistency (just Groovy 3). We already support this:

def map = [:]println Date[*:map]
Let me know if you have other thoughts.

Cheers, Paul.