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

Reply via email to