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

Hi gurus and nubys,

Again here to bother you :slight_smile:

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 :slight_smile:

(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 :wink:

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.

Hi gurus and nubys,

Again here to bother you :slight_smile:

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 :slight_smile:

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

···

On Tue, Nov 18, 2003 at 06:37:16PM +0900, gabriele renzi wrote:

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://puyo.cjb.net ]===

?

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.

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 :slight_smile:

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:

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

> >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 :slight_smile:

···

il Tue, 18 Nov 2003 21:05:59 +0900, Michael Neumann mneumann@ntecs.de 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

···

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

Hi,

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

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

[…]

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 :slight_smile:

Me, too :slight_smile:

Regards,

Michael

···

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

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 :slight_smile:

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

						matz.

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

···

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 )

matz@ruby-lang.org (Yukihiro Matsumoto) wrote:

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? :slight_smile: 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?”

···


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

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

···

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

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

···

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 :slight_smile:

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

Hi,

Thanks for clearing that up! Is there some reason why you chose
double asterisks (**)? Are we running out of punctuation? :slight_smile: 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.
···

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