You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@groovy.apache.org by Paolo Di Tommaso <pa...@gmail.com> on 2020/04/01 12:56:08 UTC

Re: About eliminating ambiguities of method call with closure argument

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 <mg...@arscreat.com> 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

Posted by Paolo Di Tommaso <pa...@gmail.com>.
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 <pa...@asert.com.au> 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.ditommaso@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 <mg...@arscreat.com> 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

Posted by Paul King <pa...@asert.com.au>.
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 <pa...@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 <mg...@arscreat.com> 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
>>
>>
>>