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/

Reply via email to