Yukihiro Matsumoto wrote:
> It's for method delegation. Currently we do
>
> def foo(*args)
> bar(*args)
> end
>
> for method delegation. Under my proposal, this delegation would still
> work fine, since we have named arguments appear twice, otherwise we
> must change the code as
>
> def foo(*args, **keys)
> bar(*args, **keys)
> end
>
> everywhere, to just do delegation.
This is sinking worse and worse into a stenchy quagmire. If someone
puts **keys in the parameters then it makes sense for the keys NOT to
appear in args. I know you want to remain backward compatable so
without **keys then the keys will appear in args. But how does one say
they want any number of ordered parameters but NO named parameters? I
suppose you just can't. Moreover the args won't be cleanly separated.
So this doesn't do us much good, I'll still be pop'n off trailing
hashes :( Really, think about that!
---
Thinking about reusing named parameters vs. adding key arguments
(better?) I recant on my previous statement of their being little
difference. The later does have one clear disadvantage: it requires a
choice --which parameters will be fixed and which will be keyed. Since
you can't have it both ways, it's really going to tie you down.
Consider this scenario:
You have a method already
def foo(a,b=1,c=2)
Now it's been a bother b/c you want to sometimes call it as foo(a,c).
But you can't. To get around, you've done what we've all done at one
point or another, created an extra method
def foo2(a,c=2,b=1)
Now along comes matz' keyd args. Does it help? Can you deprecate foo2
which you never really wanted in the first place and use?
def foo(a,b:1,c:2)
You can but, ugh, that's serious backward compatabilty breakage!!! So
what to do? Do you add YAM (yet another method) #foo3 for this? Do you
get tricky with it and do
def foo(a,b=1,c=2,b2:1,c2:2)
b = b || b2
c = c || c2
Well a little better, but now you have TWO DIFFERENT names for each
parameter and you could have just as well done this with a trailing
hash. The keyed args didn't buy you much of anything. Nope, it just
doesn't do us much good.
Buy let's say instead, here comes along the named parameters approach
like Sydney's. What happens? Easy peasy. Deprecate #foo2 (add a
warning) and your done. You can start using #foo in the new way
'foo(a,c:x)' as it suits you and backward compatability is maintained.
---
In anycase case one of the nice things about named args, should you
with to change a parameter name, you can offer both during a transition
period, in fact you may want to offer a few alternatives anyway to make
usage a bit more fluid.
def foo( beer:, beers:, beer_bottles: )
b = beer || beers || beer_bottles
A way to specify an OR in the signiture would be nice with something
like this too. Say:
def foo( beer: | beers: | beer_bottles: )
b = beer # doesn't matter which.
But again the problem that starts to arise here are _very large
signitures_. And again to me this indicatates a real need for some type
of Signture class one can use to define them and plug them in where
needed, even reuse them. Such an object would give ultimate reflexion
too.
---
Just some comparisions:
foo(:foo=>:do, :bar=>:re, :baz=>:mi) # today
foo(foo=>:do, bar=>:re, baz=>:mi) # minor adj.
foo(foo: :do, bar: :re, baz: :mi) # colon notation
foo(foo:`do, bar:`re, baz:`mi) # alt. symbol
---
BTW, those of you who do get me --I'm not trying to make some major
coherent argument. I'm just pointing out various vantages.
T.