Re: About eliminating ambiguities of method call with closure argument

2020-04-01 Thread Paolo Di Tommaso
I see, then I agree that it's not a big issue.

I was confused because I saw that Gradle supports that syntax. Not
understanding how they can, then?



Cheers, p

On Wed, Apr 1, 2020 at 3:30 PM Paul King  wrote:

> Groovy 2.5 and earlier don't support this form. But yes, if any Groovy 3
> DSLs were created in the last few weeks (or longer if we count betas/RCs)
> and they used this form, then they would break.
>
> Cheers, Paul.
>
> On Wed, Apr 1, 2020 at 10:56 PM Paolo Di Tommaso <
> paolo.ditomm...@gmail.com> wrote:
>
>> Arriving late to this thread, therefore not sure it has already
>> discussed, but have you taken in consideration that changing the method
>> call argument interpretation for the case 1, eg.
>>
>> meth
>> { p ->
>> }
>>
>> it will break all DSL in which the user scripts use this form? Just
>> thinking Gradle for example.
>>
>>
>> Cheers,
>> Paolo
>>
>>
>> On Mon, Mar 30, 2020 at 3:06 PM MG  wrote:
>>
>>> I see, that's a though one, then, if one wants people to be able to put
>>> heir braces where they want*...
>>>
>>> I have turned this back and forth in my mind, and I think the current
>>> Groovy 2.5.x behavior is actually a good/practical compromise, even though
>>> it might appear confusing at first in some cases.
>>>
>>> Rationale:
>>>
>>> *Alternative case 1: Having a the closure on a new line always being
>>> separate from the previous line*
>>>
>>> This would prohibit Groovy code where a closure is used like a block
>>> construct (a very powerful Groovy pattern imho) to be written as (e.g.):
>>>
>>> void myDatabaseProcessingMethod() {
>>>  // The closure following the next line will be passed as parameter
>>> to the forEachResultSetRow method
>>> sqe.forEachResultSetRow("select * from PERSON")
>>>  {
>>> // many lines of result row processing
>>> }
>>>
>>> // Note: Forcing people to write this with a line-continuation
>>> character to me would make no sense, e.g.:
>>> sqe.forEachResultSetRow("select * from PERSON") \
>>>  {
>>> // many lines of result row processing
>>> }
>>> }
>>>
>>> forcing people to put opening brackets on the same line as the
>>> forEachResultSetRow call, thereby potentially breaking their coding style.
>>>
>>> *Alternative case 2: Having a the closure on a new line always being
>>> bound to the previous line*
>>>
>>> This would force Spock (and maybe other DSL) users to use a semicolon at
>>> the end of line 1 in your example, which is a breaking change. It also
>>> could lead to silently failing code.
>>>
>>>
>>> *Conclusion*
>>>
>>> So I would keep the Groovy 2.5.x behavior, but if I absolutely had to
>>> choose one of the above options, I would go with the opposite of what you
>>> propose, and always bind the closure to the previous line, since otherwise
>>> there would be no acceptable way for the closure-as-block-construct pattern
>>> to be able to support having the block construct start on its own line (I
>>> don't see putting in a line continuation character as a viable solution
>>> here), whereas for DSLs putting in a semicolon in these cases would imho be
>>> OK (legacy breaking changes/silently failing code put aside).
>>>
>>> (The only other ideas I have is to support making the parsing behavior
>>> switchable, enabling one of the above behaviors through e.g. an
>>> "@ParseSpock" annotation (with always binding to the previous line being
>>> the default behavior), or by allowing a DSL/library developer to qualify
>>> whether a closure parameter can be bound from the next line or not; but 1)
>>> I have no idea if that is even technically feasible, and 2) I doubt we
>>> would want to go down that route.)
>>>
>>> Cheers,
>>> mg
>>>
>>> *Note: I have put opening braces on the same line since programming C in
>>> the 80s, so personally have no problem with this :-)
>>>
>>>
>>>
>>> On 29/03/2020 04:25, Daniel.Sun wrote:
>>>
>>> Hi MG,
>>>
>>>  Understood. Some spock code care the differences, e.g. the following
>>> code
>>> ```
>>>  modification| expected
>>>  { Instant i, ZoneId z -> i.plusSeconds(1) } | defaultInstant.plusSeconds(1)
>>> ```
>>>
>>> is expected to parsed as 2 binary expressions:
>>>
>>> ```
>>>  modification| expected
>>> ```
>>> and
>>> ```
>>>  { Instant i, ZoneId z -> i.plusSeconds(1) } | defaultInstant.plusSeconds(1)
>>> ```
>>>
>>>
>>> Cheers,
>>> Daniel.Sun
>>>
>>>
>>>
>>> -
>>> Apache Groovy committer & PMC member
>>> Blog: http://blog.sunlan.me
>>> Twitter: @daniel_sun
>>>
>>> --
>>> Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
>>>
>>>
>>>


Re: About eliminating ambiguities of method call with closure argument

2020-04-01 Thread Paul King
Groovy 2.5 and earlier don't support this form. But yes, if any Groovy 3
DSLs were created in the last few weeks (or longer if we count betas/RCs)
and they used this form, then they would break.

Cheers, Paul.

On Wed, Apr 1, 2020 at 10:56 PM Paolo Di Tommaso 
wrote:

> Arriving late to this thread, therefore not sure it has already discussed,
> but have you taken in consideration that changing the method call argument
> interpretation for the case 1, eg.
>
> meth
> { p ->
> }
>
> it will break all DSL in which the user scripts use this form? Just
> thinking Gradle for example.
>
>
> Cheers,
> Paolo
>
>
> On Mon, Mar 30, 2020 at 3:06 PM MG  wrote:
>
>> I see, that's a though one, then, if one wants people to be able to put
>> heir braces where they want*...
>>
>> I have turned this back and forth in my mind, and I think the current
>> Groovy 2.5.x behavior is actually a good/practical compromise, even though
>> it might appear confusing at first in some cases.
>>
>> Rationale:
>>
>> *Alternative case 1: Having a the closure on a new line always being
>> separate from the previous line*
>>
>> This would prohibit Groovy code where a closure is used like a block
>> construct (a very powerful Groovy pattern imho) to be written as (e.g.):
>>
>> void myDatabaseProcessingMethod() {
>>  // The closure following the next line will be passed as parameter
>> to the forEachResultSetRow method
>> sqe.forEachResultSetRow("select * from PERSON")
>>  {
>> // many lines of result row processing
>> }
>>
>> // Note: Forcing people to write this with a line-continuation
>> character to me would make no sense, e.g.:
>> sqe.forEachResultSetRow("select * from PERSON") \
>>  {
>> // many lines of result row processing
>> }
>> }
>>
>> forcing people to put opening brackets on the same line as the
>> forEachResultSetRow call, thereby potentially breaking their coding style.
>>
>> *Alternative case 2: Having a the closure on a new line always being
>> bound to the previous line*
>>
>> This would force Spock (and maybe other DSL) users to use a semicolon at
>> the end of line 1 in your example, which is a breaking change. It also
>> could lead to silently failing code.
>>
>>
>> *Conclusion*
>>
>> So I would keep the Groovy 2.5.x behavior, but if I absolutely had to
>> choose one of the above options, I would go with the opposite of what you
>> propose, and always bind the closure to the previous line, since otherwise
>> there would be no acceptable way for the closure-as-block-construct pattern
>> to be able to support having the block construct start on its own line (I
>> don't see putting in a line continuation character as a viable solution
>> here), whereas for DSLs putting in a semicolon in these cases would imho be
>> OK (legacy breaking changes/silently failing code put aside).
>>
>> (The only other ideas I have is to support making the parsing behavior
>> switchable, enabling one of the above behaviors through e.g. an
>> "@ParseSpock" annotation (with always binding to the previous line being
>> the default behavior), or by allowing a DSL/library developer to qualify
>> whether a closure parameter can be bound from the next line or not; but 1)
>> I have no idea if that is even technically feasible, and 2) I doubt we
>> would want to go down that route.)
>>
>> Cheers,
>> mg
>>
>> *Note: I have put opening braces on the same line since programming C in
>> the 80s, so personally have no problem with this :-)
>>
>>
>>
>> On 29/03/2020 04:25, Daniel.Sun wrote:
>>
>> Hi MG,
>>
>>  Understood. Some spock code care the differences, e.g. the following
>> code
>> ```
>>  modification| expected
>>  { Instant i, ZoneId z -> i.plusSeconds(1) } | defaultInstant.plusSeconds(1)
>> ```
>>
>> is expected to parsed as 2 binary expressions:
>>
>> ```
>>  modification| expected
>> ```
>> and
>> ```
>>  { Instant i, ZoneId z -> i.plusSeconds(1) } | defaultInstant.plusSeconds(1)
>> ```
>>
>>
>> Cheers,
>> Daniel.Sun
>>
>>
>>
>> -
>> Apache Groovy committer & PMC member
>> Blog: http://blog.sunlan.me
>> Twitter: @daniel_sun
>>
>> --
>> Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
>>
>>
>>


Re: About eliminating ambiguities of method call with closure argument

2020-04-01 Thread Paolo Di Tommaso
Arriving late to this thread, therefore not sure it has already discussed,
but have you taken in consideration that changing the method call argument
interpretation for the case 1, eg.

meth
{ p ->
}

it will break all DSL in which the user scripts use this form? Just
thinking Gradle for example.


Cheers,
Paolo


On Mon, Mar 30, 2020 at 3:06 PM MG  wrote:

> I see, that's a though one, then, if one wants people to be able to put
> heir braces where they want*...
>
> I have turned this back and forth in my mind, and I think the current
> Groovy 2.5.x behavior is actually a good/practical compromise, even though
> it might appear confusing at first in some cases.
>
> Rationale:
>
> *Alternative case 1: Having a the closure on a new line always being
> separate from the previous line*
>
> This would prohibit Groovy code where a closure is used like a block
> construct (a very powerful Groovy pattern imho) to be written as (e.g.):
>
> void myDatabaseProcessingMethod() {
>  // The closure following the next line will be passed as parameter to
> the forEachResultSetRow method
> sqe.forEachResultSetRow("select * from PERSON")
>  {
> // many lines of result row processing
> }
>
> // Note: Forcing people to write this with a line-continuation
> character to me would make no sense, e.g.:
> sqe.forEachResultSetRow("select * from PERSON") \
>  {
> // many lines of result row processing
> }
> }
>
> forcing people to put opening brackets on the same line as the
> forEachResultSetRow call, thereby potentially breaking their coding style.
>
> *Alternative case 2: Having a the closure on a new line always being bound
> to the previous line*
>
> This would force Spock (and maybe other DSL) users to use a semicolon at
> the end of line 1 in your example, which is a breaking change. It also
> could lead to silently failing code.
>
>
> *Conclusion*
>
> So I would keep the Groovy 2.5.x behavior, but if I absolutely had to
> choose one of the above options, I would go with the opposite of what you
> propose, and always bind the closure to the previous line, since otherwise
> there would be no acceptable way for the closure-as-block-construct pattern
> to be able to support having the block construct start on its own line (I
> don't see putting in a line continuation character as a viable solution
> here), whereas for DSLs putting in a semicolon in these cases would imho be
> OK (legacy breaking changes/silently failing code put aside).
>
> (The only other ideas I have is to support making the parsing behavior
> switchable, enabling one of the above behaviors through e.g. an
> "@ParseSpock" annotation (with always binding to the previous line being
> the default behavior), or by allowing a DSL/library developer to qualify
> whether a closure parameter can be bound from the next line or not; but 1)
> I have no idea if that is even technically feasible, and 2) I doubt we
> would want to go down that route.)
>
> Cheers,
> mg
>
> *Note: I have put opening braces on the same line since programming C in
> the 80s, so personally have no problem with this :-)
>
>
>
> On 29/03/2020 04:25, Daniel.Sun wrote:
>
> Hi MG,
>
>  Understood. Some spock code care the differences, e.g. the following
> code
> ```
>  modification| expected
>  { Instant i, ZoneId z -> i.plusSeconds(1) } | defaultInstant.plusSeconds(1)
> ```
>
> is expected to parsed as 2 binary expressions:
>
> ```
>  modification| expected
> ```
> and
> ```
>  { Instant i, ZoneId z -> i.plusSeconds(1) } | defaultInstant.plusSeconds(1)
> ```
>
>
> Cheers,
> Daniel.Sun
>
>
>
> -
> Apache Groovy committer & PMC member
> Blog: http://blog.sunlan.me
> Twitter: @daniel_sun
>
> --
> Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
>
>
>


Re: About eliminating ambiguities of method call with closure argument

2020-03-30 Thread MG
I see, that's a though one, then, if one wants people to be able to put 
heir braces where they want*...


I have turned this back and forth in my mind, and I think the current 
Groovy 2.5.x behavior is actually a good/practical compromise, even 
though it might appear confusing at first in some cases.


Rationale:

*Alternative case 1: Having a the closure on a new line always being 
separate from the previous line*


This would prohibit Groovy code where a closure is used like a block 
construct (a very powerful Groovy pattern imho) to be written as (e.g.):


void myDatabaseProcessingMethod() {
     // The closure following the next line will be passed as parameter 
to the forEachResultSetRow method

    sqe.forEachResultSetRow("select * from PERSON")
     {
        // many lines of result row processing
    }

    // Note: Forcing people to write this with a line-continuation 
character to me would make no sense, e.g.:

    sqe.forEachResultSetRow("select * from PERSON") \
     {
        // many lines of result row processing
    }
}

forcing people to put opening brackets on the same line as the 
forEachResultSetRow call, thereby potentially breaking their coding style.


*Alternative case 2: Having a the closure on a new line always being 
bound to the previous line*


This would force Spock (and maybe other DSL) users to use a semicolon at 
the end of line 1 in your example, which is a breaking change. It also 
could lead to silently failing code.



*Conclusion*

So I would keep the Groovy 2.5.x behavior, but if I absolutely had to 
choose one of the above options, I would go with the opposite of what 
you propose, and always bind the closure to the previous line, since 
otherwise there would be no acceptable way for the 
closure-as-block-construct pattern to be able to support having the 
block construct start on its own line (I don't see putting in a line 
continuation character as a viable solution here), whereas for DSLs 
putting in a semicolon in these cases would imho be OK (legacy breaking 
changes/silently failing code put aside).


(The only other ideas I have is to support making the parsing behavior 
switchable, enabling one of the above behaviors through e.g. an 
"@ParseSpock" annotation (with always binding to the previous line being 
the default behavior), or by allowing a DSL/library developer to qualify 
whether a closure parameter can be bound from the next line or not; but 
1) I have no idea if that is even technically feasible, and 2) I doubt 
we would want to go down that route.)


Cheers,
mg

*Note: I have put opening braces on the same line since programming C in 
the 80s, so personally have no problem with this :-)




On 29/03/2020 04:25, Daniel.Sun wrote:

Hi MG,

  Understood. Some spock code care the differences, e.g. the following
code
```
  modification| expected
  { Instant i, ZoneId z -> i.plusSeconds(1) } | defaultInstant.plusSeconds(1)
```

is expected to parsed as 2 binary expressions:

```
  modification| expected
```
 and
```
  { Instant i, ZoneId z -> i.plusSeconds(1) } | defaultInstant.plusSeconds(1)
```


Cheers,
Daniel.Sun



-
Apache Groovy committer & PMC member
Blog: http://blog.sunlan.me
Twitter: @daniel_sun

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




Re: About eliminating ambiguities of method call with closure argument

2020-03-29 Thread Jochen Theodorou

On 29.03.20 14:17, Paul King wrote:

Groovy's original rule was that a newline terminates a statement when it
could sensibly finish (successfully complete an expression) at that
point. So if you've opened a curly brace or bracket, for instance, the
newline would not auto-terminate an expression/statement.

The rule was later expanded with some lookahead to also merge lines when
the subsequent line couldn't be a valid statement in its own right. This
allows the following for example in Groovy 3:

def truth = maybe
   && possibly


For me the whole problem here is actually Java. People did always write
things similar to this:

"""
memberNames.stream().filter((s) -> s.startsWith("A"))
 .map(String::toUpperCase)
 .forEach(System.out::println);
"""

and IDEs like Intellij IDEA are actually forcing you into this style
quite a bit. The dot is not our problem though, it is the curly brace,
plus and minus in combination with optional return.

"""
def x = "some long text"
+ "another line"
"""

As we all know for Groovy this can mean two expression statements or one
while in

"""
def x = "some long text" +
"another line"
"""

it is very clear for the compiler that the lines belong together. So if
we make the first PLUS - example two statements we essentially "broke"
Java code.


So I was thinking we could do something intelligent with the compiler
and react differently if we have the last line or not... only that will
not solve the Spock problem at all.

So I have another alternative to suggest (besides ditching trying to be
so exact source compatible with Java), and that is:

* make plus and minus always align to the line before, essentially
disabling standalone unary plus and minus. If you want to return them,
you will have to write return.

* make Closure and block on the next line always detached from the line
before. If they are supposed to belong together, then the curly brace
has to be on the line before.


Coming back to the examples before:

```
meth
{ p ->
}
```

and

```
a | meth
{ p ->
}
```

will be two expression statements, while

```
meth { p ->
}
```

will be one.

And yes, I fully expect this to break existing code. And yes, that is
basically an inconsistent rule, since we handle +/- different from {...
though there is a difference between a syntax element like { and a
binary/unary operator

bye Jochen







Re: About eliminating ambiguities of method call with closure argument

2020-03-29 Thread Paul King
Groovy's original rule was that a newline terminates a statement when it
could sensibly finish (successfully complete an expression) at that point.
So if you've opened a curly brace or bracket, for instance, the newline
would not auto-terminate an expression/statement.

The rule was later expanded with some lookahead to also merge lines when
the subsequent line couldn't be a valid statement in its own right. This
allows the following for example in Groovy 3:

def truth = maybe
  && possibly

The string concatenation example doesn't work because of the
unaryPlus/unaryMinus operators. I'd be keen to do a GEP to see those
removed (obviously retained for numbers but no longer overridable) for
Groovy 4, then we could also support the String concatenation example and a
bunch of edge cases we currently can't support could be handled (e.g. we
currently support "def x = -0.4" but not "def y = -.4"). But that is a
separate issue in any case.

The issue at hand for GROOVY-9484 is whether we can simplify our grammar
rules and the exceptional cases that users need to remember. There are
several paths which lead to simpler rules than we have now. Some of those
would impact existing Spock code. If we put our thinking caps on we might
even be able to find alternative (even better?) solutions for Spock.

It would certainly also be good to capture the whitespace rules more
clearly in our documentation.


Paul.



On Sun, Mar 29, 2020 at 11:03 AM Remko Popma  wrote:

>
> > On Mar 29, 2020, at 0:19, Milles, Eric (TR Tech, Content & Ops) <
> eric.mil...@thomsonreuters.com> wrote:
> >
> > Is there any language that differentiates between one space and
> multiple whitespaces as a separator?  My experience with C, C++, Java,
> Groovy, etc. is that any number of whitespaces are the same in terms of
> separation between tokens.
> Not really:
>
> String accepted = "a" +
> "b" // works, gives "ab"
>
> String bad = "a"
> + "b" // compile error
>
> So, white space is significant in Groovy.
>
> >
> > In terms of parsing, you can't tell that an identifier is a method name
> -- you mention below closure follows method name -- you don't know until
> semantic analysis and possibly runtime in terms of dynamic Groovy if an
> identifier refers to a method name.
> >
> >
> > Can the user insert a semicolon to disambiguate?
> > ```
> > a | meth ; // now the parser knows this statement is over
> > { p ->
> > }
> > ```
> >
> > I don't think you are ever going to see an end to ambiguous constructs
> due to optional parentheses  and semicolons.
> >
> > -Original Message-
> > From: Daniel.Sun 
> > Sent: Friday, March 27, 2020 10:06 PM
> > To: d...@groovy.incubator.apache.org
> > Subject: About eliminating ambiguities of method call with closure
> argument
> >
> > Hi all,
> >
> >   Current groovy grammar of method call contains the following
> ambiguities, which are odd for users. For example,
> >
> > 1) method call with closure argument. That means the closure on the next
> line could be treated as argument of method `meth` ``` meth { p -> } ```
> >
> > 2) binary expression and closure expression. That means the closure is
> not an argument.
> > ```
> > a | meth
> > { p ->
> > }
> > ```
> >
> >   I propose to unify the grammar of closure arguments: when closure
> follows method name directly, it is an argument, otherwise it is just
> standalone closure. For example,
> >
> > 3) method call with closure argument
> > ```
> > meth { p ->
> > }
> > ```
> >
> > 4) variable and closure
> > ```
> > meth
> > { p ->
> > }
> > ```
> >
> >   Luckily, groovy-parser project containing source code of some
> famous groovy projects, none of which are broken because of the proposed
> change[1].
> >
> >   Here is a JIRA ticket[2] to track the proposed change, and here is
> the PR[3] to implement the change.
> >
> >   Any thoughts?
> >
> > Cheers,
> > Daniel Sun
> > [1]
> https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdanielsun1106%2Fgroovy-parser%2Fcommits%2FGROOVY-9484data=02%7C01%7Ceric.milles%40thomsonreuters.com%7Cbc5bd8c149104982c52b08d7d2c503df%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637209615925168880sdata=qdhNufAqJP8kpOtsz1QWwz2b06pR%2F1v5loQnNcuWWRM%3Dreserved=0
> > [2]
> https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fissues.apache.org%2Fjira%2Fbrowse%2FGROOVY-9484data=02%7C01%7Ceric.milles%40thomsonreuters.com%7Cbc5bd8c149104982c52b08d7d2c503df%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637209615925168880sdata=Z3FyviGcsG4EtvIGiAv889dG%2F2p%2FhqClAED998%2BnT98%3Dreserved=0
> > [3]
> https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Fgroovy%2Fpull%2F1211data=02%7C01%7Ceric.milles%40thomsonreuters.com%7Cbc5bd8c149104982c52b08d7d2c503df%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637209615925168880sdata=iXdv8OT3BMIyno8R3TlLclEB1%2BSd%2BxPlCaxhacydSqA%3Dreserved=0
> >
> >
> >
> >
> > -
> > Apache Groovy committer & PMC 

Re: About eliminating ambiguities of method call with closure argument

2020-03-28 Thread Daniel.Sun
Nice catch ;-)

Cheers,
Daniel.Sun



-
Apache Groovy committer & PMC member 
Blog: http://blog.sunlan.me 
Twitter: @daniel_sun 

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


Re: About eliminating ambiguities of method call with closure argument

2020-03-28 Thread Daniel.Sun
Hi Jochen,

> How about unifying the other way around and make 1 and 2 both a method
> call with a closure for meth?

 Groovy 3 has already unified them by accident... but some spock code is
broken, so we are trying to find a way to please everyone ;-)

```
 modification| expected
 { Instant i, ZoneId z -> i.plusSeconds(1) } | defaultInstant.plusSeconds(1)
```
(See https://issues.apache.org/jira/browse/GROOVY-9484)

Cheers,
Daniel Sun



-
Apache Groovy committer & PMC member 
Blog: http://blog.sunlan.me 
Twitter: @daniel_sun 

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


Re: About eliminating ambiguities of method call with closure argument

2020-03-28 Thread Daniel.Sun
Hi MG,

 Understood. Some spock code care the differences, e.g. the following
code 
```
 modification| expected
 { Instant i, ZoneId z -> i.plusSeconds(1) } | defaultInstant.plusSeconds(1)
```

is expected to parsed as 2 binary expressions:

```
 modification| expected
```
and
```
 { Instant i, ZoneId z -> i.plusSeconds(1) } | defaultInstant.plusSeconds(1)
```


Cheers,
Daniel.Sun



-
Apache Groovy committer & PMC member 
Blog: http://blog.sunlan.me 
Twitter: @daniel_sun 

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


RE: About eliminating ambiguities of method call with closure argument

2020-03-28 Thread Daniel.Sun
Actually, we have already force some code style... But the code style is not
unified:

2.5.8 parses the following code as a variable and a method call with closure
argument
```
a | meth { p ->

}
```

Let's add a newline. 2.5.8 parses the following code as binary expression
and a closure
```
a | meth
{ p ->

}
```

But 3.0.2 parses the above both code as a variable and a method call with
closure argument.

To be frank, I am inclined to accept the behaviour of 3.0.2, it is unified,
but it breaks some spock code:

```
 modification| expected
 { Instant i, ZoneId z -> i.plusSeconds(1) } | defaultInstant.plusSeconds(1)
```
(See https://issues.apache.org/jira/browse/GROOVY-9484)


Cheers,
Daniel.Sun



-
Apache Groovy committer & PMC member 
Blog: http://blog.sunlan.me 
Twitter: @daniel_sun 

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


RE: About eliminating ambiguities of method call with closure argument

2020-03-28 Thread Daniel.Sun


AFAIK, Groovy learned quite a few design ideas from many great language,
e.g. Ruby. The optional parentheses feature was inspired by Ruby. The
feature makes Groovy more friendly as DSL to users, but ambiguities
introduced... Ruby has similar troubles(See the following link)

https://stackoverflow.com/questions/26480823/why-does-white-space-affect-ruby-function-calls

Cheers,
Daniel.Sun






-
Apache Groovy committer & PMC member 
Blog: http://blog.sunlan.me 
Twitter: @daniel_sun 

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


Re: About eliminating ambiguities of method call with closure argument

2020-03-28 Thread Remko Popma


> On Mar 29, 2020, at 0:19, Milles, Eric (TR Tech, Content & Ops) 
>  wrote:
> 
> Is there any language that differentiates between one space and multiple 
> whitespaces as a separator?  My experience with C, C++, Java, Groovy, etc. is 
> that any number of whitespaces are the same in terms of separation between 
> tokens.
Not really:

String accepted = "a" +
"b" // works, gives "ab"

String bad = "a"
+ "b" // compile error 

So, white space is significant in Groovy. 

> 
> In terms of parsing, you can't tell that an identifier is a method name -- 
> you mention below closure follows method name -- you don't know until 
> semantic analysis and possibly runtime in terms of dynamic Groovy if an 
> identifier refers to a method name.
> 
> 
> Can the user insert a semicolon to disambiguate?
> ```
> a | meth ; // now the parser knows this statement is over
> { p ->
> }
> ```
> 
> I don't think you are ever going to see an end to ambiguous constructs due to 
> optional parentheses  and semicolons.
> 
> -Original Message-
> From: Daniel.Sun  
> Sent: Friday, March 27, 2020 10:06 PM
> To: d...@groovy.incubator.apache.org
> Subject: About eliminating ambiguities of method call with closure argument
> 
> Hi all,
> 
>   Current groovy grammar of method call contains the following 
> ambiguities, which are odd for users. For example,
> 
> 1) method call with closure argument. That means the closure on the next line 
> could be treated as argument of method `meth` ``` meth { p -> } ```
> 
> 2) binary expression and closure expression. That means the closure is not an 
> argument.
> ```
> a | meth
> { p ->
> }
> ```
> 
>   I propose to unify the grammar of closure arguments: when closure 
> follows method name directly, it is an argument, otherwise it is just 
> standalone closure. For example,
> 
> 3) method call with closure argument
> ```
> meth { p ->
> }
> ```
> 
> 4) variable and closure
> ```
> meth
> { p ->
> }
> ```
> 
>   Luckily, groovy-parser project containing source code of some famous 
> groovy projects, none of which are broken because of the proposed change[1].
> 
>   Here is a JIRA ticket[2] to track the proposed change, and here is the 
> PR[3] to implement the change.
> 
>   Any thoughts?
> 
> Cheers,
> Daniel Sun
> [1] 
> https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdanielsun1106%2Fgroovy-parser%2Fcommits%2FGROOVY-9484data=02%7C01%7Ceric.milles%40thomsonreuters.com%7Cbc5bd8c149104982c52b08d7d2c503df%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637209615925168880sdata=qdhNufAqJP8kpOtsz1QWwz2b06pR%2F1v5loQnNcuWWRM%3Dreserved=0
> [2] 
> https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fissues.apache.org%2Fjira%2Fbrowse%2FGROOVY-9484data=02%7C01%7Ceric.milles%40thomsonreuters.com%7Cbc5bd8c149104982c52b08d7d2c503df%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637209615925168880sdata=Z3FyviGcsG4EtvIGiAv889dG%2F2p%2FhqClAED998%2BnT98%3Dreserved=0
> [3] 
> https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Fgroovy%2Fpull%2F1211data=02%7C01%7Ceric.milles%40thomsonreuters.com%7Cbc5bd8c149104982c52b08d7d2c503df%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637209615925168880sdata=iXdv8OT3BMIyno8R3TlLclEB1%2BSd%2BxPlCaxhacydSqA%3Dreserved=0
> 
> 
> 
> 
> -
> Apache Groovy committer & PMC member
> Blog: 
> https://nam02.safelinks.protection.outlook.com/?url=http%3A%2F%2Fblog.sunlan.medata=02%7C01%7Ceric.milles%40thomsonreuters.com%7Cbc5bd8c149104982c52b08d7d2c503df%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637209615925168880sdata=70Xxc7%2Bg6iF7bhVISTRF48hxQkUb5%2F7iuuofMttDF2o%3Dreserved=0
> Twitter: @daniel_sun 
> 
> --
> Sent from: 
> https://nam02.safelinks.protection.outlook.com/?url=http%3A%2F%2Fgroovy.329449.n5.nabble.com%2FGroovy-Dev-f372993.htmldata=02%7C01%7Ceric.milles%40thomsonreuters.com%7Cbc5bd8c149104982c52b08d7d2c503df%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637209615925168880sdata=bGnd%2BrQj%2FPKljTtkIdT2fFyGF9aQb0QgR1RzQlWRPsY%3Dreserved=0


Re: About eliminating ambiguities of method call with closure argument

2020-03-28 Thread Jochen Theodorou

On 28.03.20 04:06, Daniel.Sun wrote:

Hi all,

Current groovy grammar of method call contains the following
ambiguities, which are odd for users. For example,

1) method call with closure argument. That means the closure on the next
line could be treated as argument of method `meth`
```
meth
{ p ->
}
```

2) binary expression and closure expression. That means the closure is not
an argument.
```
a | meth
{ p ->
}
```

I propose to unify the grammar of closure arguments: when closure
follows method name directly, it is an argument, otherwise it is just
standalone closure. For example,

3) method call with closure argument
```
meth { p ->
}
```

4) variable and closure
```
meth
{ p ->
}
```

[...]

How about unifying the other way around and make 1 and 2 both a method
call with a closure for meth?

bye Jochen


Re: About eliminating ambiguities of method call with closure argument

2020-03-28 Thread MG

Hi Daniel,

good to hear you seem to be well :-)

Maybe I am missing something, but right now I don't see where writing a 
standalone closure in the code would makes sense, since it is not 
assigned to anything, and its creation has no side effects (?)


The only application I can see is calling it immediately inline, which I 
have sometimes done in the past to do e.g. some if-then-else-cascade 
based calculations depending on parameters/variables from surrounding 
scope  and assign the result to a final variable (without having to 
introduce a method).
I have however switched to using a static eval method for that case, 
since it is much cleaner:


final x = { ...  }.call()

final x = eval { ... }

with statically imported (trivial) eval method

static  T eval(final Closure cls) { cls() }

Cheers,
mg


On 28/03/2020 04:06, Daniel.Sun wrote:

Hi all,

Current groovy grammar of method call contains the following
ambiguities, which are odd for users. For example,

1) method call with closure argument. That means the closure on the next
line could be treated as argument of method `meth`
```
meth
{ p ->
}
```

2) binary expression and closure expression. That means the closure is not
an argument.
```
a | meth
{ p ->
}
```

I propose to unify the grammar of closure arguments: when closure
follows method name directly, it is an argument, otherwise it is just
standalone closure. For example,

3) method call with closure argument
```
meth { p ->
}
```

4) variable and closure
```
meth
{ p ->
}
```

Luckily, groovy-parser project containing source code of some famous
groovy projects, none of which are broken because of the proposed change[1].

Here is a JIRA ticket[2] to track the proposed change, and here is
the PR[3] to implement the change.

Any thoughts?

Cheers,
Daniel Sun
[1] https://github.com/danielsun1106/groovy-parser/commits/GROOVY-9484
[2] https://issues.apache.org/jira/browse/GROOVY-9484
[3] https://github.com/apache/groovy/pull/1211




-
Apache Groovy committer & PMC member
Blog: http://blog.sunlan.me
Twitter: @daniel_sun

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




RE: About eliminating ambiguities of method call with closure argument

2020-03-28 Thread Milles, Eric (TR Tech, Content & Ops)
Additionally, you are forcing the hand of users in terms of brace style if you 
require a closure to have its opening brace on the same line as the method 
call/name.

-Original Message-
From: Milles, Eric (TR Tech, Content & Ops)  
Sent: Saturday, March 28, 2020 10:20 AM
To: dev@groovy.apache.org
Subject: RE: About eliminating ambiguities of method call with closure argument

Is there any language that differentiates between one space and multiple 
whitespaces as a separator?  My experience with C, C++, Java, Groovy, etc. is 
that any number of whitespaces are the same in terms of separation between 
tokens.

In terms of parsing, you can't tell that an identifier is a method name -- you 
mention below closure follows method name -- you don't know until semantic 
analysis and possibly runtime in terms of dynamic Groovy if an identifier 
refers to a method name.


Can the user insert a semicolon to disambiguate?
```
a | meth ; // now the parser knows this statement is over { p -> } ```

I don't think you are ever going to see an end to ambiguous constructs due to 
optional parentheses  and semicolons.

-Original Message-
From: Daniel.Sun 
Sent: Friday, March 27, 2020 10:06 PM
To: d...@groovy.incubator.apache.org
Subject: About eliminating ambiguities of method call with closure argument

Hi all,

   Current groovy grammar of method call contains the following 
ambiguities, which are odd for users. For example,

1) method call with closure argument. That means the closure on the next line 
could be treated as argument of method `meth` ``` meth { p -> } ```

2) binary expression and closure expression. That means the closure is not an 
argument.
```
a | meth
{ p ->
}
```

   I propose to unify the grammar of closure arguments: when closure 
follows method name directly, it is an argument, otherwise it is just 
standalone closure. For example,

3) method call with closure argument
```
meth { p ->
}
```

4) variable and closure
```
meth
{ p ->
}
```

   Luckily, groovy-parser project containing source code of some famous 
groovy projects, none of which are broken because of the proposed change[1].

   Here is a JIRA ticket[2] to track the proposed change, and here is the 
PR[3] to implement the change.

   Any thoughts?

Cheers,
Daniel Sun
[1] 
https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdanielsun1106%2Fgroovy-parser%2Fcommits%2FGROOVY-9484data=02%7C01%7Ceric.milles%40thomsonreuters.com%7C55746422d5ec42d281f508d7d32b7c3a%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637210056033516926sdata=lnEsUtHUU%2FqUXzlEvJA41AkWkXX0g6Ur2o2b5Vye3bM%3Dreserved=0
[2] 
https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fissues.apache.org%2Fjira%2Fbrowse%2FGROOVY-9484data=02%7C01%7Ceric.milles%40thomsonreuters.com%7C55746422d5ec42d281f508d7d32b7c3a%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637210056033526920sdata=fVNF6la9ogHDBgM8uj%2FstRAqnUUXThrlHq%2BEdK7Qq%2BY%3Dreserved=0
[3] 
https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Fgroovy%2Fpull%2F1211data=02%7C01%7Ceric.milles%40thomsonreuters.com%7C55746422d5ec42d281f508d7d32b7c3a%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637210056033526920sdata=alJQcVNgAdYlyLyk%2FpD%2BBMo3dLGKhwqlkV3LTbR%2BxS8%3Dreserved=0




-
Apache Groovy committer & PMC member
Blog: 
https://nam02.safelinks.protection.outlook.com/?url=http%3A%2F%2Fblog.sunlan.medata=02%7C01%7Ceric.milles%40thomsonreuters.com%7C55746422d5ec42d281f508d7d32b7c3a%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637210056033526920sdata=IQu4X3%2BFtC7BAVDSqKqGnAcgkicXXiI8XLH8mqI4g8s%3Dreserved=0
Twitter: @daniel_sun 

--
Sent from: 
https://nam02.safelinks.protection.outlook.com/?url=http%3A%2F%2Fgroovy.329449.n5.nabble.com%2FGroovy-Dev-f372993.htmldata=02%7C01%7Ceric.milles%40thomsonreuters.com%7C55746422d5ec42d281f508d7d32b7c3a%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637210056033526920sdata=jEmfYhHiJgpJJePXCtrIl9pChfqfBlWSPv4ebp%2FpliY%3Dreserved=0


RE: About eliminating ambiguities of method call with closure argument

2020-03-28 Thread Milles, Eric (TR Tech, Content & Ops)
Is there any language that differentiates between one space and multiple 
whitespaces as a separator?  My experience with C, C++, Java, Groovy, etc. is 
that any number of whitespaces are the same in terms of separation between 
tokens.

In terms of parsing, you can't tell that an identifier is a method name -- you 
mention below closure follows method name -- you don't know until semantic 
analysis and possibly runtime in terms of dynamic Groovy if an identifier 
refers to a method name.


Can the user insert a semicolon to disambiguate?
```
a | meth ; // now the parser knows this statement is over
{ p ->
}
```

I don't think you are ever going to see an end to ambiguous constructs due to 
optional parentheses  and semicolons.

-Original Message-
From: Daniel.Sun  
Sent: Friday, March 27, 2020 10:06 PM
To: d...@groovy.incubator.apache.org
Subject: About eliminating ambiguities of method call with closure argument

Hi all,

   Current groovy grammar of method call contains the following 
ambiguities, which are odd for users. For example,

1) method call with closure argument. That means the closure on the next line 
could be treated as argument of method `meth` ``` meth { p -> } ```

2) binary expression and closure expression. That means the closure is not an 
argument.
```
a | meth
{ p ->
}
```

   I propose to unify the grammar of closure arguments: when closure 
follows method name directly, it is an argument, otherwise it is just 
standalone closure. For example,

3) method call with closure argument
```
meth { p ->
}
```

4) variable and closure
```
meth
{ p ->
}
```

   Luckily, groovy-parser project containing source code of some famous 
groovy projects, none of which are broken because of the proposed change[1].

   Here is a JIRA ticket[2] to track the proposed change, and here is the 
PR[3] to implement the change.

   Any thoughts?

Cheers,
Daniel Sun
[1] 
https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdanielsun1106%2Fgroovy-parser%2Fcommits%2FGROOVY-9484data=02%7C01%7Ceric.milles%40thomsonreuters.com%7Cbc5bd8c149104982c52b08d7d2c503df%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637209615925168880sdata=qdhNufAqJP8kpOtsz1QWwz2b06pR%2F1v5loQnNcuWWRM%3Dreserved=0
[2] 
https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fissues.apache.org%2Fjira%2Fbrowse%2FGROOVY-9484data=02%7C01%7Ceric.milles%40thomsonreuters.com%7Cbc5bd8c149104982c52b08d7d2c503df%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637209615925168880sdata=Z3FyviGcsG4EtvIGiAv889dG%2F2p%2FhqClAED998%2BnT98%3Dreserved=0
[3] 
https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Fgroovy%2Fpull%2F1211data=02%7C01%7Ceric.milles%40thomsonreuters.com%7Cbc5bd8c149104982c52b08d7d2c503df%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637209615925168880sdata=iXdv8OT3BMIyno8R3TlLclEB1%2BSd%2BxPlCaxhacydSqA%3Dreserved=0




-
Apache Groovy committer & PMC member
Blog: 
https://nam02.safelinks.protection.outlook.com/?url=http%3A%2F%2Fblog.sunlan.medata=02%7C01%7Ceric.milles%40thomsonreuters.com%7Cbc5bd8c149104982c52b08d7d2c503df%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637209615925168880sdata=70Xxc7%2Bg6iF7bhVISTRF48hxQkUb5%2F7iuuofMttDF2o%3Dreserved=0
Twitter: @daniel_sun 

--
Sent from: 
https://nam02.safelinks.protection.outlook.com/?url=http%3A%2F%2Fgroovy.329449.n5.nabble.com%2FGroovy-Dev-f372993.htmldata=02%7C01%7Ceric.milles%40thomsonreuters.com%7Cbc5bd8c149104982c52b08d7d2c503df%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637209615925168880sdata=bGnd%2BrQj%2FPKljTtkIdT2fFyGF9aQb0QgR1RzQlWRPsY%3Dreserved=0