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

G

gabriele renzi

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.
 
M

Michael Neumann

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
 
G

gabriele renzi

il Tue, 18 Nov 2003 21:05:59 +0900, Michael Neumann
<[email protected]> ha scritto::

?
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 :)

Expression-orientedness. Any expression should be allowed, even the
following:
<snip>
ok, nice explanation thanks.

Conflicts with default values when argument is ommited.

well, I don't see it as 'conflict' much like 'overlap'
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):.... print a
.... print b
....
3
434


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 :)
 
M

Michael Neumann

il Tue, 18 Nov 2003 21:05:59 +0900, Michael Neumann


well, I thinmk the two are unified in python (I may be wrong):
.... print a
.... print b
....
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
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Again, Rite explanation needed (keyword args and new hash syntax)"

|>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.
 
G

gabriele renzi

il Tue, 18 Nov 2003 23:19:42 +0900, Michael Neumann
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 :=)
 
G

gabriele renzi

il Wed, 19 Nov 2003 02:44:29 +0900, (e-mail address removed) (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 :)
 
G

Greg McIntyre

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?
 
G

gabriele renzi

il Wed, 19 Nov 2003 13:37:35 +1100, Greg McIntyre <[email protected]>
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
 
M

Michael Neumann

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
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Again, Rite explanation needed (keyword args and new hash syntax)"

|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.
 
G

Greg McIntyre

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

Thanks for clearing that up! Is there some reason why you chose
double asterisks (**)? Are we running out of punctuation? :) To me it
seems a little too much like the * operator repeated.

def f(*args); end
f(**[[1,2,3]]) # => f(1,2,3) # logically, to me

But not so because we need ** to do this

def f(**args); end
f(**{:a => 1, :b => 2, :c => 3}) # => f(a:1,b:2,c:3)

Hmm... looks at keyboard for more punctuation...

def f(~args); end
f(~{:a => 1, :b => 2, :c => 3}) # => f(a:1,b:2,c:3)

def f(+args); end
f(+{:a => 1, :b => 2, :c => 3}) # => f(a:1,b:2,c:3)

Isn't there a more natural syntax? Hmm...

def f(a, b, [arguments])
# arguments is an Array
end
f(a, b, 1, 2, 3)
f(a, b, [1, 2, 3].arguments) # => f(a,b,1,2,3)

def f(a, b, {keywords})
# keywords is a Hash
end
f(a, b, x:10, y:20)
f(a, b, {:x => 10}.keywords) # => f(a,b,x:10)

What do people think? I know * is borrowed from somewhere but it's not
very intuitive. As a university tutor, students always point at it and
say, "What's *that* do?"
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Again, Rite explanation needed (keyword args and new hash syntax)"

|Thanks for clearing that up! Is there some reason why you chose
|double asterisks (**)? Are we running out of punctuation? :) To me it
|seems a little too much like the * operator repeated.

It's borrowed from Python, to show we have no prejudice for it.

|Isn't there a more natural syntax? Hmm...
|
| def f(a, b, [arguments])
| # arguments is an Array
| end
| f(a, b, 1, 2, 3)
| f(a, b, [1, 2, 3].arguments) # => f(a,b,1,2,3)
|
| def f(a, b, {keywords})
| # keywords is a Hash
| end
| f(a, b, x:10, y:20)
| f(a, b, {:x => 10}.keywords) # => f(a,b,x:10)
|
|What do people think? I know * is borrowed from somewhere but it's not
|very intuitive. As a university tutor, students always point at it and
|say, "What's *that* do?"

I am not full against the idea, but I don't think it's worth enough
for incompatibility. Students are easy to remember once they're told,
they are not THAT stupid (I hope).

matz.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top