[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Again, Rite explanation needed (keyword args and new hash syntax

gabriele renzi

11/18/2003 9:33:00 AM

Hi gurus and nubys,

Again here to bother you :)

Please note that I'm not here to start a flame. I actually want to
understand matz' and dev/core choices, please excuse me if I sound
rude.


This is the supposed behaviour for kwd args:
---
def f(a,b: 2 , **kwd)
p [a,b,kwd]
end

f(1) #=> [1,2,{}]
f(1,b:5) #=>[1,5,{}]
f(1,b:5,c:6) #=>[1,5,{:c=>6}]

---

I wonder:
why we introduce the ':' syntax ?

Why can't we call a kwd arg like
f(1,b=5)

?

I suppose this is to avoid conflicts with normal assignment..
but what's wrong with making go away the assignment in method calling?
?

OTOH, why we have to define kwd args with
f(a,b:2)

instead of
f(a,b=10)

?

if f(a,b:10) cames in default argument with '=' actually become
useless?

I suppose matz refused the current keyword args syntax as it is found
in python.
I just wonder why :)

(maybe just because we don't have a () operator?)


PS
btw the 'a: c' syntax for hash is really cool.

I always hate to type 'a'=>b or :a=>b.


PPS
I'd love to see : and => unified as

'a=>b is the same that a: b and it works like
hash[a]=b if var a is defined or like hash[:a]=b if a is not already
defined'

but I'm just dreaming,remeber:
when *you* will write *your* language you'll follow *your* POLS.

Too bad matz' logic is so obvious to me most of the time, this keeps
me away from writing MyLang ;)




PPPS
literals, and method argument definition, are actually embedded micro
languages.
It seem normal to me that '{a=>b}' could work differently from 'a = b'
(i.e. look if the var exist and act differently).

Nobody expects a string literal or a regexp literal to work like the
rest of the code.

But we expect this from Arrays and Hashes (and somewy Ranges).
This must mean something.
Possibly that I need more coffe in the morning.


12 Answers

Michael Neumann

11/18/2003 12:06:00 PM

0

On Tue, Nov 18, 2003 at 06:37:16PM +0900, gabriele renzi wrote:
> Hi gurus and nubys,
>
> Again here to bother you :)
>
> Please note that I'm not here to start a flame. I actually want to
> understand matz' and dev/core choices, please excuse me if I sound
> rude.
>
>
> This is the supposed behaviour for kwd args:
> ---
> def f(a,b: 2 , **kwd)
> p [a,b,kwd]
> end
>
> f(1) #=> [1,2,{}]
> f(1,b:5) #=>[1,5,{}]
> f(1,b:5,c:6) #=>[1,5,{:c=>6}]
>
> ---
>
> I wonder:
> why we introduce the ':' syntax ?
>
> Why can't we call a kwd arg like
> f(1,b=5)

b=5 is an expression and is allowed everywhere to appear.
With your suggestions, this would be no more true.

Matz, instead, introduces new hash syntax:

{b: 5, c: 6} # => {:b => 5, :c => 6}

In Ruby1, we are emulating keyword arguments this way:

f(:b => 5, :c => 6)

With this new hash syntax, it would become:

f(b: 5, c: 6)

Which IMO looks much cleaner.

And you would not break any existent programs, e.g.

f(line=gets, ...)
puts line

would still work.

> I suppose this is to avoid conflicts with normal assignment..
> but what's wrong with making go away the assignment in method calling?
> ?

Expression-orientedness. Any expression should be allowed, even the
following:

def b(k) p k end
x=Object.new

b( begin class << x; def hallo() end; end; x end )

This really distinguishes it from Python, which IIRC is very restricted
in this case (things might have changed).

> OTOH, why we have to define kwd args with
> f(a,b:2)
>
> instead of
> f(a,b=10)

Conflicts with default values when argument is ommited.

A very complex example that will probably be possilbe with Rite:

def foo(a, x=5, *args, b: 42, c: nil, **keys, &block)
end

foo() # => ERROR

foo(1) # => a=1, x=5, args=[], b=42, c=nil, keys={}, block=nil

foo(1, 2, 3, 4, c: 5, port: 8080) {...}
# => a=1, x=2, args=[3,4], b=42, c=5, keys={port: 8080}, block={...}

Maybe too complex, but at least *very* powerful (I don't want to write
the parser for this :-).

> if f(a,b:10) cames in default argument with '=' actually become
> useless?

But b:10 is a keyword argument, whereas b=10 would be a numbered
argument (as in Python).

> I suppose matz refused the current keyword args syntax as it is found
> in python.
> I just wonder why :)

Sorry, I forgot how this is done in python. Can you show an example?

The good thing with matz's keyword arguments is, that it will not break
existing applications. At the first moment, I didn't liked matz's idea,
but now, it think it's really cool.

Regards,

Michael


gabriele renzi

11/18/2003 1:31:00 PM

0

il Tue, 18 Nov 2003 21:05:59 +0900, Michael Neumann
<mneumann@ntecs.de> ha scritto::

?
>>
>> Why can't we call a kwd arg like
>> f(1,b=5)
>
>b=5 is an expression and is allowed everywhere to appear.
>With your suggestions, this would be no more true.
<snip>
ok, thanks, now I understand why b: a syntax is needed to call stuff.



>
>And you would not break any existent programs, e.g.
>
> f(line=gets, ...)
> puts line
>
>would still work.

well, we're breaking existing stuff anyway (block vars, class vars,
constant lookup) taht's the point in a major release :)


>> I suppose this is to avoid conflicts with normal assignment..
>> but what's wrong with making go away the assignment in method calling?
>> ?
>
>Expression-orientedness. Any expression should be allowed, even the
>following:
<snip>
ok, nice explanation thanks.


>> OTOH, why we have to define kwd args with
>> f(a,b:2)
>>
>> instead of
>> f(a,b=10)
>
>Conflicts with default values when argument is ommited.
>

well, I don't see it as 'conflict' much like 'overlap'

>
>> if f(a,b:10) cames in default argument with '=' actually become
>> useless?
>
>But b:10 is a keyword argument, whereas b=10 would be a numbered
>argument (as in Python).

well, I thinmk the two are unified in python (I may be wrong):
>>> def f(a=1,b=10):
.... print a
.... print b
....
>>> f(1)
1
10
>>> f(1,4)
1
4
>>> f(a=3,b=434)
3
434


<snip>
>
>The good thing with matz's keyword arguments is, that it will not break
>existing applications. At the first moment, I didn't liked matz's idea,
>but now, it think it's really cool.
>

I'm sure it's cool that's why I'm trying to understand it :)

Michael Neumann

11/18/2003 2:20:00 PM

0

On Tue, Nov 18, 2003 at 10:32:16PM +0900, gabriele renzi wrote:
> il Tue, 18 Nov 2003 21:05:59 +0900, Michael Neumann
> <mneumann@ntecs.de> ha scritto::
> [...]
> >But b:10 is a keyword argument, whereas b=10 would be a numbered
> >argument (as in Python).
>
> well, I thinmk the two are unified in python (I may be wrong):
> >>> def f(a=1,b=10):
> .... print a
> .... print b
> ....
> >>> f(1)
> 1
> 10
> >>> f(1,4)
> 1
> 4
> >>> f(a=3,b=434)
> 3
> 434

Ah, thanks. But think about this one in Python:

def f(a, b=10, *args, **keys):
print a, b, args, keys

f(1, b=2, c=4, d=8) # all right here

# want to use b as keyword argument
f(1, "a", "b", "c", b=2, c=4) # => ERROR

The problem arises, as it's undecidable if b is a keyword argument or
not, so that *args cannot be used in this case (or I am missing
something here).

> I'm sure it's cool that's why I'm trying to understand it :)

Me, too :-)


Regards,

Michael


matz

11/18/2003 5:44:00 PM

0

Hi,

In message "Re: Again, Rite explanation needed (keyword args and new hash syntax)"
on 03/11/18, gabriele renzi <surrender_it@rc1.vip.ukl.yahoo.com> writes:

|>And you would not break any existent programs, e.g.
|>
|> f(line=gets, ...)
|> puts line
|>
|>would still work.
|
|well, we're breaking existing stuff anyway (block vars, class vars,
|constant lookup) taht's the point in a major release :)

Just trade off. I thought we don't need to break compatibility here.

matz.


gabriele renzi

11/18/2003 8:53:00 PM

0

il Tue, 18 Nov 2003 23:19:42 +0900, Michael Neumann
<mneumann@ntecs.de> ha scritto::

>On Tue, Nov 18, 2003 at 10:32:16PM +0900, gabriele renzi wrote:

>
>Ah, thanks. But think about this one in Python:
>
> def f(a, b=10, *args, **keys):
> print a, b, args, keys
>
> f(1, b=2, c=4, d=8) # all right here
>
> # want to use b as keyword argument
> f(1, "a", "b", "c", b=2, c=4) # => ERROR
>
>The problem arises, as it's undecidable if b is a keyword argument or
>not, so that *args cannot be used in this case (or I am missing
>something here).

mh.. yes, this seem the case were our kwd would be better. thanks for
the discussion :=)



gabriele renzi

11/18/2003 9:44:00 PM

0

il Wed, 19 Nov 2003 02:44:29 +0900, matz@ruby-lang.org (Yukihiro
Matsumoto) ha scritto::


>|well, we're breaking existing stuff anyway (block vars, class vars,
>|constant lookup) taht's the point in a major release :)
>
>Just trade off. I thought we don't need to break compatibility here.

thank you and Michael for the replies enough for me :)

Greg McIntyre

11/19/2003 2:38:00 AM

0


I'm a bit confused by this too.

---
def f(a, b: 2, **kwd)
p [a,b,kwd]
end

f(1) #=> [1,2,{}]
f(1,b:5) #=>[1,5,{}]
f(1,b:5,c:6) #=>[1,5,{:c=>6}]

---

Is the double asterisk (**) especially for grouping the rest of the
arguments into a hash the same way that a single asterisk groups the
rest of the arguments into an array? If so,

f(1,b:5,6,7,8) # => ? runtime error?

Can I still use position to in the argument list and forgo the
keywordiness?

f(1,5) # => [1,5,{}]

Can I change the order of the arguments or leave as many as I like out?
Shouldn't that be included in the primary example of this? It is the
point, isn't it?

def g(a:1,b:2,c:3)
[a,b,c]
end

g(c:5,b:6) # => [1, 6, 5]

Is that right?

--
Greg McIntyre ======[ greg@puyo.cjb.net ]===[ http://pu... ]===

gabriele renzi

11/19/2003 7:15:00 AM

0

il Wed, 19 Nov 2003 13:37:35 +1100, Greg McIntyre <greg@puyo.cjb.net>
ha scritto::

well, I answer based on keyword args as I think they will work...

>
>Is the double asterisk (**) especially for grouping the rest of the
>arguments into a hash the same way that a single asterisk groups the
>rest of the arguments into an array?

yes, and I bet matz would allow
method_with_kwd_args (**hash )
just likwe we do
method_with_blk(&proc)
or
method_with_variable_args(*proc)

> If so,
>
> f(1,b:5,6,7,8) # => ? runtime error?

I think so

>Can I still use position to in the argument list and forgo the
>keywordiness?
>
> f(1,5) # => [1,5,{}]

yes you can


>Can I change the order of the arguments or leave as many as I like out?
>Shouldn't that be included in the primary example of this? It is the
>point, isn't it?

exactly

> def g(a:1,b:2,c:3)
> [a,b,c]
> end
>
> g(c:5,b:6) # => [1, 6, 5]
>
>Is that right?

I think this is right

Michael Neumann

11/19/2003 7:46:00 AM

0

On Wed, Nov 19, 2003 at 04:17:17PM +0900, gabriele renzi wrote:
> il Wed, 19 Nov 2003 13:37:35 +1100, Greg McIntyre <greg@puyo.cjb.net>
> ha scritto::
> >Is the double asterisk (**) especially for grouping the rest of the
> >arguments into a hash the same way that a single asterisk groups the
> >rest of the arguments into an array?
>
> yes, and I bet matz would allow
> method_with_kwd_args (**hash )

Yes, that's IMHO better than what's allowed in Ruby1:

def method_with_kwd_args (hash)

I am not sure if the above (hash) will become obsolete, but I would vote
for it.


Regards,

Michael


matz

11/19/2003 12:11:00 PM

0

Hi,

In message "Re: Again, Rite explanation needed (keyword args and new hash syntax)"
on 03/11/19, Greg McIntyre <greg@puyo.cjb.net> writes:

|I'm a bit confused by this too.
|
|---
|def f(a, b: 2, **kwd)
| p [a,b,kwd]
|end
|
|f(1) #=> [1,2,{}]
|f(1,b:5) #=>[1,5,{}]
|f(1,b:5,c:6) #=>[1,5,{:c=>6}]
|
|---
|
|Is the double asterisk (**) especially for grouping the rest of the
|arguments into a hash the same way that a single asterisk groups the
|rest of the arguments into an array? If so,

Basic Rule:
Double asterisk for grouping the rest of keyword arguments. Keyword
arguments don't mix positional arguments (including optional ones).

| f(1,b:5,6,7,8) # => ? runtime error?

Syntax Error. Every keyword argument come after positional
arguments.

|Can I still use position to in the argument list and forgo the
|keywordiness?
|
| f(1,5) # => [1,5,{}]

Argument Error. f() requires single positional argument, you
specified two.

|Can I change the order of the arguments or leave as many as I like out?
|Shouldn't that be included in the primary example of this? It is the
|point, isn't it?
|
| def g(a:1,b:2,c:3)
| [a,b,c]
| end
|
| g(c:5,b:6) # => [1, 6, 5]

Yes. Order doesn't matter for keyword arguments.

matz.