You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@groovy.apache.org by "Edinson E. Padrón Urdaneta" <ed...@gmail.com> on 2015/08/14 19:10:10 UTC

[Question] Variable Argument Lists, Named Arguments, Optional Parameters and Multiple assignment

Greetings, everyone,

I have a couple of questions I would like to address with you (if possible)
and the best way to explain them (potentially) is through the following
lines of code

    def foo(Map kwargs, Object bar) { /*...*/ }                     //
Instead of this ...
    def foo(Object bar, Map kwargs) { /*...*/ }                     // ...
wouldn't this be more clear ...
    def foo(Object bar, Object[] args) { /*...*/ }                  // ...
just like this one? ...
    def foo(Object bar, Object[] args, Map kwargs) { /*...*/ }      // ...
and we could combine both this way

    def foo(Object a=null, Object b) { /*...*/ }                    //
Shouldn't it rise an error?

    def (int a, int b, int[] rest) = [1, 2, 3, 4]                   //
Given this ...
    assert a == 1 && b == 2 && rest == [3, 4]                       // ...
why something like this doesn't hold?


Gist mirror ~> https://gist.github.com/EPadronU/c1d2455b67b400905530

Thanks in advance for your time

RE: [Question] Variable Argument Lists, Named Arguments, Optional Parameters and Multiple assignment

Posted by "KARR, DAVID" <dk...@att.com>.
> -----Original Message-----
> From: Jochen Theodorou [mailto:blackdrag@gmx.org]
> Sent: Monday, August 17, 2015 10:27 AM
> To: users@groovy.incubator.apache.org
> Subject: Re: [Question] Variable Argument Lists, Named Arguments,
> Optional Parameters and Multiple assignment
> 
> hi,
> 
> yeah, Python is a different beast than Groovy in manner matters. If
> named arguments would have been a default mechanism on the JVM we
> would
> certainly have supported something like Python does. But in Groovy
> arguments are no dictionary unless you define it as something like
> that
> using a Map... And even then the Groovy named arguments solution is
> quite half-hearted looking compared to Python. But the problem is,
> we
> cannot influence the JVM internals, while Python and its
> interpreter/runtime are supporting each other.
> 
> As for your questions... They have been perfectly legal to ask,
> don't
> worry about it. You are welcome to ask more in the future, though I
> suggest the user list ;)
> 
> btw.. what IRC channel was it you guys where communicating over?

##groovy on freenode.

> bye blackdrag
> 
> Am 15.08.2015 18:54, schrieb Edinson E. Padrón Urdaneta:
> > Greetings, Mr. Theodorou​,
> >
> > I'm very thankful. Your answer was very insightful and clear, I
> > appreciate it.
> >
> > I'm a very novice developer (less than 2 years in the field) with
> a
> > Python background and it can be noticed in the nature of my
> questions.
> > Don't get me wrong, I don't want to use Groovy just like I use
> Python
> > nor to transform the first into the latter, but I was curious
> about why
> > Groovy took a different approach than Python's for the 'same'
> features.
> > Now that I know the reasons behind the design my curiosity has
> been
> > satisfied in those particular subjects (at least for now) and I
> can use
> > them without bringing some level of conflict to my mind.
> >
> > Thanks a lot for everything.
> 
> 
> --
> Jochen "blackdrag" Theodorou
> blog: http://blackdragsview.blogspot.com/


Re: [Question] Variable Argument Lists, Named Arguments, Optional Parameters and Multiple assignment

Posted by "Edinson E. Padrón Urdaneta" <ed...@gmail.com>.
Thank you, Paul. I guess my English reading skills tricked me there (I'm
not native but I'm getting better).

Thank you all for be so nice and helpful :)

Cheers.

On Mon, Aug 17, 2015 at 4:59 PM, Paul King <pa...@asert.com.au> wrote:

>
> This is the users list. I think what Jochen is suggesting is that you
> should feel free to send tricky questions directly to this list rather than
> using IRC/chat. Chat is great for immediate responses but you will get more
> eyeballs on your question in the mailing list which are also then archived
> and can help others get answers in the future too.
>
> Cheers, Paul.
>
> On 18/08/2015 7:16 AM, Edinson E. Padrón Urdaneta wrote:
>
>>     ​... though I suggest the user list ;)
>>
>>
>> ​Isn't this the mailing list `users@groovy.incubator.apache.org <mailto:
>> users@groovy.incubator.apache.org>`​? If not: I'm so sorry, that's the
>> email address I'm using as the receiver of this messages, so I don't know
>> what I'm doing wrong :\
>>
>
>
> ---
> This email has been checked for viruses by Avast antivirus software.
> https://www.avast.com/antivirus
>
>

Re: [Question] Variable Argument Lists, Named Arguments, Optional Parameters and Multiple assignment

Posted by Paul King <pa...@asert.com.au>.
This is the users list. I think what Jochen is suggesting is that you should feel free to send tricky questions directly to this list rather than using IRC/chat. Chat is great for immediate responses but you will get more eyeballs on your question in the mailing list which are also then archived and can help others get answers in the future too.

Cheers, Paul.

On 18/08/2015 7:16 AM, Edinson E. Padrón Urdaneta wrote:
>     ​... though I suggest the user list ;)
>
>
> ​Isn't this the mailing list `users@groovy.incubator.apache.org <ma...@groovy.incubator.apache.org>`​? If not: I'm so sorry, that's the email address I'm using as the receiver of this messages, so I don't know what I'm doing wrong :\


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus


Re: [Question] Variable Argument Lists, Named Arguments, Optional Parameters and Multiple assignment

Posted by "Edinson E. Padrón Urdaneta" <ed...@gmail.com>.
>
> ​... though I suggest the user list ;)
>

​Isn't this the mailing list `users@groovy.incubator.apache.org`​? If not:
I'm so sorry, that's the email address I'm using as the receiver of this
messages, so I don't know what I'm doing wrong :\

Re: [Question] Variable Argument Lists, Named Arguments, Optional Parameters and Multiple assignment

Posted by Jochen Theodorou <bl...@gmx.org>.
hi,

yeah, Python is a different beast than Groovy in manner matters. If 
named arguments would have been a default mechanism on the JVM we would 
certainly have supported something like Python does. But in Groovy 
arguments are no dictionary unless you define it as something like that 
using a Map... And even then the Groovy named arguments solution is 
quite half-hearted looking compared to Python. But the problem is, we 
cannot influence the JVM internals, while Python and its 
interpreter/runtime are supporting each other.

As for your questions... They have been perfectly legal to ask, don't 
worry about it. You are welcome to ask more in the future, though I 
suggest the user list ;)

btw.. what IRC channel was it you guys where communicating over?

bye blackdrag

Am 15.08.2015 18:54, schrieb Edinson E. Padrón Urdaneta:
> Greetings, Mr. Theodorou​,
>
> I'm very thankful. Your answer was very insightful and clear, I
> appreciate it.
>
> I'm a very novice developer (less than 2 years in the field) with a
> Python background and it can be noticed in the nature of my questions.
> Don't get me wrong, I don't want to use Groovy just like I use Python
> nor to transform the first into the latter, but I was curious about why
> Groovy took a different approach than Python's for the 'same' features.
> Now that I know the reasons behind the design my curiosity has been
> satisfied in those particular subjects (at least for now) and I can use
> them without bringing some level of conflict to my mind.
>
> Thanks a lot for everything.


-- 
Jochen "blackdrag" Theodorou
blog: http://blackdragsview.blogspot.com/


Re: [Question] Variable Argument Lists, Named Arguments, Optional Parameters and Multiple assignment

Posted by "Edinson E. Padrón Urdaneta" <ed...@gmail.com>.
Greetings, Mr. Theodorou​,

I'm very thankful. Your answer was very insightful and clear, I appreciate
it.

I'm a very novice developer (less than 2 years in the field) with a Python
background and it can be noticed in the nature of my questions. Don't get
me wrong, I don't want to use Groovy just like I use Python nor to
transform the first into the latter, but I was curious about why Groovy
took a different approach than Python's for the 'same' features. Now that I
know the reasons behind the design my curiosity has been satisfied in those
particular subjects (at least for now) and I can use them without bringing
some level of conflict to my mind.

Thanks a lot for everything.

Re: [Question] Variable Argument Lists, Named Arguments, Optional Parameters and Multiple assignment

Posted by Jochen Theodorou <bl...@gmx.org>.
Am 14.08.2015 19:10, schrieb Edinson E. Padrón Urdaneta:
> Greetings, everyone,
>
> I have a couple of questions I would like to address with you (if
> possible) and the best way to explain them (potentially) is through the
> following lines of code
>
>      def foo(Map kwargs, Object bar) { /*...*/ }                     //
> Instead of this ...
>      def foo(Object bar, Map kwargs) { /*...*/ }                     //
> ... wouldn't this be more clear ...

you can define both signatures no problem, but if you want the map 
semantics on method calls it has to be the first argument.

>      def foo(Object bar, Object[] args) { /*...*/ }                  //
> ... just like this one? ...
>      def foo(Object bar, Object[] args, Map kwargs) { /*...*/ }      //
> ... and we could combine both this way

No you would not be able to combine it this way. Java semantics require 
the vargs part to be last. This leaves only

def foo(Object bar, Map kwargs, Object[] args) { /*...*/ }
def foo(Map kwargs, Object bar, Object[] args) { /*...*/ }

as possible signatures.

>      def foo(Object a=null, Object b) { /*...*/ }                    //
> Shouldn't it rise an error?

"def foo(Object a=null, Object b)" causes groovy to produce the methods

def foo(Object b) {foo(null,b)}
def foo(Object a, Object b) { /*...*/ }

So unlike the map or vargs logic, this produces an overloaded method. 
And there is a defined right-to-left order for this

def foo(a=null,b=null){...}

produces

def foo(){foo(null,null)}
def foo(a){foo(a,null)}
def foo(a,b){...}

Now keep in mind a few things:
  a) The map syntax existed before Java5 introduced vargs.
  b) Groovy can, because of its dynamic nature not reposition arguments 
easily and keep performance to a good level

Those two points have a lot of impact. Mainly (a) explains why vargs and 
the map version work quite different. But (b) explains that we had to 
decide on a fixed position to collect all those map arguments.

The Groovy compiler will for "foo(a:b, 1, b:c)" generate a call 
"foo([a:b,b:c],1)". For this kind of thing, you can basically only 
choose the end or the beginning. Had we chosen the end position, we 
would have gotten into conflict with vargs. Back then we did not know 
that, so it was more luck to do it like this. But in the end, the front 
position just looked more logically to us back then.

Also there is the difference in semantics that for foo(x,Object[] y) you 
can make a call foo(1) and get in y an empty array (all according to 
Java semantics), while for foo(Map m, y) a call foo(1) is not legal.

The later reason led to a combination of optional parameters and named 
arguments like this: def foo(Map m=[:],y), which will allow the call 
foo(1) and provide the map m with an empty map. Again the optional 
parameters part is pre Java5 and vargs.

And lastly point (b) also allows for the not using a type for the named 
arguments part: def foo(m){...} is a method that would accept 
"foo(a:b,b:c)" as well as foo(1) and is implicitly typed as Object. For 
the same reason you can use for example HashMap or LinkedHashMap instead 
of Map or Object. Map is advised for documentation purposes, but not 
required. Though I have to add, that HashMap and LinkedHashMap are 
implementation details and could in theory change.

>      def (int a, int b, int[] rest) = [1, 2, 3, 4]                   //
> Given this ...
>      assert a == 1 && b == 2 && rest == [3, 4]                       //
> ... why something like this doesn't hold?

I guess simply because nobody had this idea back then. On the other 
hand... if the right side is an infinite (well up to Integer.MAX_VALUE) 
structure, then this kind of approach would lead to problems. And what 
would you expect if rest is not given a type?

like here:

def n = 0
def cl = {n2->n+=n2}

class Helper {
     def cl
     Object getAt(int i){cl(i)}
}

def h = new Helper(cl:cl)

def (a,b,c,d,e) = h
assert a == 0
assert b == 1
assert c == 3
assert d == 6
assert e == 10

Of course that is just playing around and nothing really useful

bye blackdrag

-- 
Jochen "blackdrag" Theodorou
blog: http://blackdragsview.blogspot.com/


Re: [Question] Variable Argument Lists, Named Arguments, Optional Parameters and Multiple assignment

Posted by "Edinson E. Padrón Urdaneta" <ed...@gmail.com>.
​Thank you, David. I assume that there's no way to achieve the behavior I
described. The following is a very naive work around I just wrote:

def multiple_assignment(int assignments, List values) {
    assert assignments >= 0

    assignments = Math.min(values.size() - 1, assignments - 1)
    values.take(assignments) << values.takeRight(values.size() -
assignments)
}

def (a, b, c) = [1, 2, 3, 4]
assert a == 1 && b == 2 && c == 3

(a, b, c) = multiple_assignment(1, [1, 2, 3, 4])
assert a == [1, 2, 3, 4] && b == null && c == null

(a, b, c) = multiple_assignment(2, [1, 2, 3, 4])
assert a == 1 && b == [2, 3, 4] && c == null

(a, b, c) = multiple_assignment(3, [1, 2, 3, 4])
assert a == 1 && b == 2 && c == [3, 4]

(a, b, c) = multiple_assignment(4, [1, 2, 3, 4])
assert a == 1 && b == 2 && c == 3

(a, b, c) = multiple_assignment(5, [1, 2, 3, 4])
assert a == 1 && b == 2 && c == 3

RE: [Question] Variable Argument Lists, Named Arguments, Optional Parameters and Multiple assignment

Posted by "KARR, DAVID" <dk...@att.com>.
For everyone else, this is the “question” originally phrased on IRC that lead to my earlier question about “leftover” args.  That was the only concrete question I was able to pull out of this.

Edinson, to address the last “question” from this code sample, this was answered earlier in this list, from the question I phrased (search the archives for ‘Assigning "leftover" args to trailing array’ for this thread).  In short, what you’re using there is called “multiple assignment”, which doesn’t work the way you’re expecting.  You might think it would work similarly to how actual parameters are assigned to varargs formal parameters, but it simply does not.

Someone else will have to address the implied questions from the earlier lines in your code sample.

From: Edinson E. Padrón Urdaneta [mailto:edinson.padron.urdaneta@gmail.com]
Sent: Friday, August 14, 2015 10:10 AM
To: users@groovy.incubator.apache.org
Subject: [Question] Variable Argument Lists, Named Arguments, Optional Parameters and Multiple assignment

Greetings, everyone,

I have a couple of questions I would like to address with you (if possible) and the best way to explain them (potentially) is through the following lines of code

    def foo(Map kwargs, Object bar) { /*...*/ }                     // Instead of this ...
    def foo(Object bar, Map kwargs) { /*...*/ }                     // ... wouldn't this be more clear ...
    def foo(Object bar, Object[] args) { /*...*/ }                  // ... just like this one? ...
    def foo(Object bar, Object[] args, Map kwargs) { /*...*/ }      // ... and we could combine both this way

    def foo(Object a=null, Object b) { /*...*/ }                    // Shouldn't it rise an error?

    def (int a, int b, int[] rest) = [1, 2, 3, 4]                   // Given this ...
    assert a == 1 && b == 2 && rest == [3, 4]                       // ... why something like this doesn't hold?


Gist mirror ~> https://gist.github.com/EPadronU/c1d2455b67b400905530

Thanks in advance for your time