Groovy 3.0: Multiline list/map arguments

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
MG
Reply | Threaded
Open this post in threaded view
|

Groovy 3.0: Multiline list/map arguments

MG
Quick question, since I just came across that again in Groovy 2.4: Will
Groovy 3.0 support passing multiline lists/maps to a method without
surrounding it with brackets ?

E.g.

def foo(List l) { ... }

could be called giving

final result = foo [
      "some rather long literal string argument",
     "another long literal string argument",
     "and so on and so forth (not the language)",
]

instead of

final result = foo ([
      "some rather long literal string argument",
     "another long literal string argument",
     "and so on and so forth (not the language)",
])



Reply | Threaded
Open this post in threaded view
|

Re: Groovy 3.0: Multiline list/map arguments

Daniel.Sun
Hi mg,

      `foo [....]` is ambiguous, parser can parse it as index expression or
parse it as method invocation without parentheses, the former is applied to
solve the ambiguity.

       Similarly, `println [1, 2, 3]` will fail too ;-)

Cheers,
Daniel.Sun




--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Users-f329450.html
MG
Reply | Threaded
Open this post in threaded view
|

Re: Groovy 3.0: Multiline list/map arguments

MG
Hi Daniel,

I know that  "println [1, 2, 3]" fails, but I literally have never
wanted to literally print a list literal ;-)

My question was related to the fact that there is only whitespace +
newline right after the opening list bracket "[", and that this syntax
variety would  conceivably not be used if someone was going for an index
expression.
Backward compatibility breaking changes aside, would the Parrot be able
to discern these cases ?

Cheers,
mg


On 06.04.2018 18:25, Daniel.Sun wrote:

> Hi mg,
>
>        `foo [....]` is ambiguous, parser can parse it as index expression or
> parse it as method invocation without parentheses, the former is applied to
> solve the ambiguity.
>
>         Similarly, `println [1, 2, 3]` will fail too ;-)
>
> Cheers,
> Daniel.Sun
>
>
>
>
> --
> Sent from: http://groovy.329449.n5.nabble.com/Groovy-Users-f329450.html
>

Reply | Threaded
Open this post in threaded view
|

Re: Groovy 3.0: Multiline list/map arguments

Daniel.Sun
Hi mg,

      It's dangerous to let blank characters determine the grammar, which is
the lesson learned from Ruby ;-)

```ruby
def f(p)
  return p * 2
end

f(3+2)+1     #  11
f (3+2)+1    #  12,  have you seen the space between `f` and `(`  ?
```
(you can try the above code at http://tryruby.org)

Cheers,
Daniel.Sun



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Users-f329450.html
MG
Reply | Threaded
Open this post in threaded view
|

Re: Groovy 3.0: Multiline list/map arguments

MG
My suggestion was not to consider allowing any whitespace to break
syntax ambiguity here, but only a newline after the opening square
bracket, i.e.:

// Still does not compile
final result = foo [ "some rather long literal string argument",
     "another long literal string argument",
     "and so on and so forth...",
]

// Parsed as foo([ ... ])  (not foo-index-access)
final result = foo [
      "some rather long literal string argument",
     "another long literal string argument",
     "and so on and so forth...",
]

If the parser can do it, it would feel Groovy to me to allow it for this
use case (Of course it could still mean "index access", but how many
people would really write an index access on foo that way ?).

Groovy 3.0 is the place to ponder such questions, imho, because breaking
changes will come anyway afaiks (Java 9 modules), so you do it here, or
not for a long time...

Would be interested what others think, or if someone has a counter
example that makes it clear it is a bad idea to go down that route,
mg


On 06.04.2018 19:49, Daniel.Sun wrote:

> Hi mg,
>
>        It's dangerous to let blank characters determine the grammar, which is
> the lesson learned from Ruby ;-)
>
> ```ruby
> def f(p)
>    return p * 2
> end
>
> f(3+2)+1     #  11
> f (3+2)+1    #  12,  have you seen the space between `f` and `(`  ?
> ```
> (you can try the above code at http://tryruby.org)
>
> Cheers,
> Daniel.Sun
>
>
>
> --
> Sent from: http://groovy.329449.n5.nabble.com/Groovy-Users-f329450.html
>

Reply | Threaded
Open this post in threaded view
|

Re: Groovy 3.0: Multiline list/map arguments

Jochen Theodorou
On 06.04.2018 21:21, MG wrote:
> My suggestion was not to consider allowing any whitespace to break
> syntax ambiguity here, but only a newline after the opening square
> bracket, i.e.:

whitespace in terms of the groovy grammar includes newline usually.

> // Still does not compile
> final result = foo [ "some rather long literal string argument",
>      "another long literal string argument",
>      "and so on and so forth...",
> ]
>
> // Parsed as foo([ ... ])  (not foo-index-access)
> final result = foo [
>       "some rather long literal string argument",
>      "another long literal string argument",
>      "and so on and so forth...",
> ]

so you want

list[0]

keep as is now and

list[
   0
]

be instead list([0])?

> If the parser can do it, it would feel Groovy to me to allow it for this
> use case (Of course it could still mean "index access", but how many
> people would really write an index access on foo that way ?).

asking "but how many people would" is always to be answered with
"potentially many"

> Groovy 3.0 is the place to ponder such questions, imho, because breaking
> changes will come anyway afaiks (Java 9 modules), so you do it here, or
> not for a long time...
>
> Would be interested what others think, or if someone has a counter
> example that makes it clear it is a bad idea to go down that route,

why not use

>> final result = foo (
>>      "some rather long literal string argument",
>>      "another long literal string argument",
>>      "and so on and so forth..."
>> )

instead and make foo use Object...? The real problem is a different one
imho.

people try things and start debugging code with println. They have for
example

return [x,y]

and change this now to

println [x,y]
return [x,y]

or log it...

Obviously they started with a list and do not want indexing at all. They
want the method call variant you propose. But in my experience this has
really been the only case where it plays a role. And I think to give it
up just because of that... give up I mean because I prefer having to
write println([x,y]) to simulate the method call, than having to
write... println.getAt([x,y]) to simulate the index. Especially since
the later requires people to actually now the method name used for the
index operation, which in most cases, they will not care about really.
And do you really want to write

println [
  x,y]

to get a method call?

bye Jochen
MG
Reply | Threaded
Open this post in threaded view
|

Re: Groovy 3.0: Multiline list/map arguments

MG
Hi Jochen,

yes newline is a whitespace in Groovy, but not every whitespace is a
newline. For me that is why Daniel's Ruby counter-example does not fit
in my case, since a newline is much more visible than a space (or tab).
Answering "how likely is something" with "in [0,1]" is always correct,
yes. But have you (or anyone else on this list) ever seen an index
access that goes over multipe lines ?

It is about the example I gave (which is actually from a Groovy test I
am working on), not about println, and the method accepting the List is
not always under your control, so changing it to accepting Object...
instead is not always possible (also what if someone has a List, then he
has to convert it to an Object array).

In your println example, why would people not assign the list to a
variable - since it is now used 2x that makes sense, also with regard to
the classic error of not updating what you print in relation to what you
return from the method.

I would also require one or more space or tab characters after the
"list" in your multiline example, i.e.

// Compiles to list([0])
list [
   0
]

instead of

// Does not compile
list[
   0
]

Cheers,
mg



On 06.04.2018 23:29, Jochen Theodorou wrote:

> On 06.04.2018 21:21, MG wrote:
>> My suggestion was not to consider allowing any whitespace to break
>> syntax ambiguity here, but only a newline after the opening square
>> bracket, i.e.:
>
> whitespace in terms of the groovy grammar includes newline usually.
>
>> // Still does not compile
>> final result = foo [ "some rather long literal string argument",
>>      "another long literal string argument",
>>      "and so on and so forth...",
>> ]
>>
>> // Parsed as foo([ ... ])  (not foo-index-access)
>> final result = foo [
>>       "some rather long literal string argument",
>>      "another long literal string argument",
>>      "and so on and so forth...",
>> ]
>
> so you want
>
> list[0]
>
> keep as is now and
>
> list[
>   0
> ]
>
> be instead list([0])?
>
>> If the parser can do it, it would feel Groovy to me to allow it for
>> this use case (Of course it could still mean "index access", but how
>> many people would really write an index access on foo that way ?).
>
> asking "but how many people would" is always to be answered with
> "potentially many"
>
>> Groovy 3.0 is the place to ponder such questions, imho, because
>> breaking changes will come anyway afaiks (Java 9 modules), so you do
>> it here, or not for a long time...
>>
>> Would be interested what others think, or if someone has a counter
>> example that makes it clear it is a bad idea to go down that route,
>
> why not use
>
>>> final result = foo (
>>>      "some rather long literal string argument",
>>>      "another long literal string argument",
>>>      "and so on and so forth..."
>>> )
>
> instead and make foo use Object...? The real problem is a different
> one imho.
>
> people try things and start debugging code with println. They have for
> example
>
> return [x,y]
>
> and change this now to
>
> println [x,y]
> return [x,y]
>
> or log it...
>
> Obviously they started with a list and do not want indexing at all.
> They want the method call variant you propose. But in my experience
> this has really been the only case where it plays a role. And I think
> to give it up just because of that... give up I mean because I prefer
> having to write println([x,y]) to simulate the method call, than
> having to write... println.getAt([x,y]) to simulate the index.
> Especially since the later requires people to actually now the method
> name used for the index operation, which in most cases, they will not
> care about really. And do you really want to write
>
> println [
>  x,y]
>
> to get a method call?
>
> bye Jochen
>