option parens and final argument as closure

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

option parens and final argument as closure

Ray Cromwell


def foo(a, c)
{
    c(a)
}

foo "hello", { it -> print it+" world" }


works but



def foo(a, c)
{
    c(a)
}

foo "hello" { it -> print it+" world" }

Does not. This feels like yet another special case where the syntax
rules should be orthogonal.  Not that it is ultra important to save the ",".

-Ray


---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

Reply | Threaded
Open this post in threaded view
|

Re: option parens and final argument as closure

graemer
It is recommended that optional parenthesis should only be used in the
most simple cases (like println). This should be written:

foo('hello') {
       println "$it world"
}

Graeme

On 6/23/06, Ray Cromwell <[hidden email]> wrote:

>
>
> def foo(a, c)
> {
>     c(a)
> }
>
> foo "hello", { it -> print it+" world" }
>
>
> works but
>
>
>
> def foo(a, c)
> {
>     c(a)
> }
>
> foo "hello" { it -> print it+" world" }
>
> Does not. This feels like yet another special case where the syntax
> rules should be orthogonal.  Not that it is ultra important to save the ",".
>
> -Ray
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list please visit:
>
>     http://xircles.codehaus.org/manage_email
>
>

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

Reply | Threaded
Open this post in threaded view
|

Re: option parens and final argument as closure

Ray Cromwell

   Yes, but if a language has too many special cases where rules that
work everywhere else, don't, it could be confusing to users. Is there
any compelling reason (say, ambiguities) why the parser shouldn't be
modified to handle this? Ruby allows it, tha is one may write

foo arg1 do .... end

I guess it might make some DSLs nicer to write, e.g.

sql "select * from foo"
{
    ...
}




Graeme Rocher wrote:
> It is recommended that optional parenthesis should only be used in the
> most simple cases (like println). This should be written:
>
> foo('hello') {
>       println "$it world"
> }
>
> Graeme
>


---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

Reply | Threaded
Open this post in threaded view
|

Re: Re: option parens and final argument as closure

tugwilson

On 23 Jun 2006, at 08:57, Ray Cromwell wrote:

>
>   Yes, but if a language has too many special cases where rules  
> that work everywhere else, don't, it could be confusing to users.  
> Is there any compelling reason (say, ambiguities) why the parser  
> shouldn't be modified to handle this? Ruby allows it, tha is one  
> may write
>
> foo arg1 do .... end
>
> I guess it might make some DSLs nicer to write, e.g.
>
> sql "select * from foo"
> {
>    ...
> }

"hello" 1

is parsed as "hello"(1)

i.e. it's a call to a method called hello with an integer parameter.

This lets us call methods with names which are not valid Groovy  
identifiers. It's widely used in Builders.

John Wilson
The Wilson Partnership
web http://www.wilson.co.uk
blog http://eek.ook.org



---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

Reply | Threaded
Open this post in threaded view
|

Re: option parens and final argument as closure

Ray Cromwell
John Wilson wrote:

>
>
>
> "hello" 1
>
> is parsed as "hello"(1)
>
> i.e. it's a call to a method called hello with an integer parameter.
>
> This lets us call methods with names which are not valid Groovy  
> identifiers. It's widely used in Builders.
>

I'm puzzled by this response. Are you saying this is why the parser
can't be modified to accept a trailing block with no parens? Otherwise,
My SQL example doesn't require strings to be treated as method names for
method invocations,

it just requires

def sql(query, c)
{
   exec(query).eachRow(c)
}

and with proper parser support you could use as

sql "select..."
{
   ...
}

instead of

sql("select...")
{
    ...
}

Granted, the optional parens could be argued to not be that big of a
deal, but Groovy is so full of "optional" stuff to save on characters
cluttering up the source, I don't see the logic for opposing this, but
not the others, unless there are sound implementation grounds.


---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

Reply | Threaded
Open this post in threaded view
|

Re: option parens and final argument as closure

Ray Cromwell
Ray Cromwell wrote:

> John Wilson wrote:
>
>>
>>
>>
>> "hello" 1
>>
>> is parsed as "hello"(1)
>>
>> i.e. it's a call to a method called hello with an integer parameter.
>>
>> This lets us call methods with names which are not valid Groovy  
>> identifiers. It's widely used in Builders.
>>
>

Nvrmind, I get it now.

sql "selct..." {closure}

will be treated potentially as

sql select({closure})

which is an ambiguity


---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

Reply | Threaded
Open this post in threaded view
|

Re: Re: option parens and final argument as closure

tugwilson
The behaviour when parameters are omitted has been achieved by a  
pragmatic mixture of argument and experiment. It took quite a long  
time and was quite painful at the time. The compromise achieved is  
not perfect but there are real benefits which we value.

We do very strongly advise people only to omit parentheses in the  
very simplest of situations (println "hello" and tag {.... in  
Bulders, for example). The behaviour in more complex situations is  
deterministic but can be surprising.

x([1]) // passes a list to x
x [1] // accesses the second element of x


John Wilson
The Wilson Partnership
web http://www.wilson.co.uk
blog http://eek.ook.org



---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email