Keyword arguments like grandma makes 'em


#1

I’m messing around with some methods trying to figure out how to offer
all the functionality I want in a clean interface and I stumbled across
an idea that may be better for keyword arguments.

Instead of

grab ‘x’, :from => ‘y’

I really wanted to write:

grab ‘x’ from ‘y’

I think everyone would prefer such a syntax if it can be done. Since
commas are used to deliminate arguments normally, it seems like it
should be possible to use parameter keywords as delimeters too.

T.


#2

Selon T. removed_email_address@domain.invalid:

grab ‘x’ from ‘y’

I think everyone would prefer such a syntax if it can be done. Since
commas are used to deliminate arguments normally, it seems like it
should be possible to use parameter keywords as delimeters too.

Congratulations, you’ve just reinvented Smalltalk :wink: (well, in Smalltalk
one
would write that: grab ‘x’ from: ‘y’, but the : is just convention, just
like !
and ? in Ruby method names). I know METAFONT can do that too, maybe in a
slightly less flexible way (I have to check that out). Of course, in the
Smalltalk way the “from:” is really part of the method name, so it’s not
exactly the same as what you’re suggesting, but it’s close enough.

As for whether I like the idea or not, I’m not quite sure yet. I’ve been
studying Smalltalk for a while, and so far I’m still not sure whether I
find
named parameters cool or annoying :slight_smile: . If it doesn’t lead to
ambiguities, I may
give my vote in favour of it. After all, it does get rid of a lot of
punctuation.

Whether this could easily be parsed and wouldn’t lead to ambiguities is
another
question though.

Christophe G…

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.


#3

Sorry I made a typo, I meant worth reading, not work reading.


#4

“Trans” removed_email_address@domain.invalid writes:

grab ‘x’ from ‘y’

I think everyone would prefer such a syntax if it can be done. Since
commas are used to deliminate arguments normally, it seems like it
should be possible to use parameter keywords as delimeters too.

Without trying to get personal or offensive, I’d recommend you
to try to implement your ideas at first. :wink:

I’m currently designing a language that will allow for that syntax,
but it is designed with that in mind. I don’t want to imagine
the effort it would take to do above in Ruby as it stands now.


#5

Without trying to get personal or offensive, I’d recommend you
to try to implement your ideas at first. :wink:

Well, I realize it’s not a walk in the park --it certainly is beyond
my present abilities, and maybe it’s not even possible. I’m just
looking at it as somehing that would A) be a desirable syntax and B)
probably possible.

On the later point, if you look at the syntax with parens in place.

grab(‘x’ from ‘y’)

I think its easier to see. The ‘from’ is not expression because their
is no ‘.’ or ‘,’ before or after.

T.


#6

Consider this example:

foo(x or y)

Using your model, the ‘or’ keyword would actually be a keyword argument
delimiter, so you would be calling the ‘foo’ method with two arguments:
‘x’, as the first positional arg, and the keyword arg ‘y’.

Alternately, if you continued to parse all reserved keywords as just
that, you would prevent methods from using any of them as keyword arg
names. You then lose a large set of useful arg labels, including ‘end’,
‘until’, ‘alias’, ‘begin’, and others.

Based on all this, I for one just don’t see a good way to have keyword
args without some sort of sigil to put them in a separate namespace
from language keywords and method names.

-Lennon


#7

I’m a fan of having optional named arguments, because a lot of the time
functions have a single argument or the arguments come in a well
established order and so you don’t want to name them, but other times
it makes the code easier to read if the arguments are named, so for
example if you are instanciating some component and overriding only a
few defaults.

So the problem is how to support both named and unnamed parameters. The
proposals for Ruby 2.0 are work reading.

One kind of obvious thing about the syntax, you need I think some way
to distinguish parameter names from expressions. Usually that ends up
being either commas or brackets or both. It is best to keep it concise
and obvious (ie. simple and following convention to some extent) if at
all possible. And of course you want your interpreter or bytecode to be
fast as well :slight_smile:

regards,

Richard.


#8

I’m not sure that’s neccessarily true. Yes it is true for ‘and’ and
‘or’ and a few others, but ‘alias’, ‘begin’ and other aren’t really
useful in the context of arguments, so they could still be used.

And how, exactly, would you decide which keywords were and weren’t
useful in method argument context, given that just about everything
aside from basic assignment in Ruby is based on method calls? Something
about that smells awfully Pythonic to me…

One of my favorite aspects of Ruby’s syntax is that every syntactic
structure is an expression which returns a useful value. While you
might not want to have a full ‘case’ switch tree inside the arglist,
the syntax does not prohibit it.

Making the overall syntax significantly more restrictive in order to
eliminate a single character sigil for keyword args (which, since most
methods require very few arguments, should be used only in the minority
of cases) is still a bad trade in my book.

Of course, for people coming to Ruby via Rails, I can see the appeal of
making keyword args as easy to use as possible, since the Rails team
seems to have a real fetish for having single “do-it-all” methods that
dispatch based on an arbitrary number of optional keyword args.

-Lennon


#9

rcoder wrote:

names. You then lose a large set of useful arg labels, including ‘end’,
‘until’, ‘alias’, ‘begin’, and others.

I’m not sure that’s neccessarily true. Yes it is true for ‘and’ and
‘or’ and a few others, but ‘alias’, ‘begin’ and other aren’t really
useful in the context of arguments, so they could still be used.

T.


#10

rj-cole wrote:

One kind of obvious thing about the syntax, you need I think some way
to distinguish parameter names from expressions. Usually that ends up
being either commas or brackets or both. It is best to keep it concise
and obvious (ie. simple and following convention to some extent) if at
all possible. And of course you want your interpreter or bytecode to be
fast as well :slight_smile:

regards,

Richard.

(Yes, I know I’m repeating myself)

I think the current way of calling a method with “named parameters” is
just fine:

def foo(options = {})
puts option[:bar] || “bar”
end

foo :bar => “bur”

The thing we need is an easier way to work with named parameters in the
method definition. I for one think this is sufficient (note that the
keyword doesn’t have to be named', it could even be a symbol, like%’):

bur' is mandatory,bar’ and `baz’ aren’t

def foo(named bur, named bar = “bar”, named baz = “baz”)
puts bur, bar, baz
end

foo :bur => “arr”, :bar => “avast”, :baz => “matey”

Collection of unknown keys should then be done like for positional
arguments: a `**keys’ in the parameter list.

def foo(named bur, named bar = “landlubber”, **baz)
baz.each { |key, value| puts “#{key} => #{value}” }
end

foo :bur => “arrr”, :pirate => “avast ye”, :sheep => “baaaah”
-> pirate => avast ye
sheep => baaaah

The reason I think symbols are appropriate as keys when calling a method
with named parameters is that I believe symbols are names. Names of
method, variables, attributes, etc. So when I type foo :bar => "baz"', I'm calling the methodfoo’, setting the parameter named bar' to the value ofbaz’ (even though I think the `=>’ operator actually means
“points to”).

This won’t disallow for Matz’ foo bar: "baz"' style. Actually, I think thekey: value’ should be added as a generic way of writing key/value
pairs in a hash, where the key is a symbol (that seems to become the
norm). These should mean the same:

connect :to => “example.com
connect to: “example.com

And a normal hash:

{a: “foo”, b: “bar”, c: “baz”}
-> {:a => “foo”, :b => “bar”, :c => “baz”}

Cheers,
Daniel


#11

rcoder wrote:

I’m not sure that’s neccessarily true. Yes it is true for ‘and’ and
‘or’ and a few others, but ‘alias’, ‘begin’ and other aren’t really
useful in the context of arguments, so they could still be used.

And how, exactly, would you decide which keywords were and weren’t
useful in method argument context, given that just about everything
aside from basic assignment in Ruby is based on method calls? Something
about that smells awfully Pythonic to me…

Well, ‘alias’ isn’t a method. In fact I think it should be gotten rid
of. #alias_method is a method and thus is preferable.

begin…end clauses aren’t methods either and I don’t see any good
reason to ever make them so. Yet I point out #begin and #end are
methods of MatchData. So I think these can be resused for keywords
arugments witouht issue.

if, case, until, loop, while, for: Except perhaps for ‘for’ I don’t see
these as much of a loss if they couldn’t be used for keywords args. In
fact ‘if’ and ‘case’ and ‘while’ I think make esspecially poor keywords
anyway. OTOH, they are rarely used for return values anyway, and
exponetially less so as direct method arguments. In fact I can’t think
of a single time I ever used a condition or loop construct as an
argument. Sso that’s the other possibility, and again not much a loss
(if any) here either.

One of my favorite aspects of Ruby’s syntax is that every syntactic
structure is an expression which returns a useful value. While you
might not want to have a full ‘case’ switch tree inside the arglist,
the syntax does not prohibit it.

Well. That’s not completely true. But it’ss certainly close. I think
the not wanting a ‘case’ switch as an argument is pretty much
universally desired. No one wants to read code like that --actaully we
wouldn’t have blocks if we wanted code like that. So prohibiting it I
doubt anyone would even notice.

Making the overall syntax significantly more restrictive in order to
eliminate a single character sigil for keyword args (which, since most
methods require very few arguments, should be used only in the minority
of cases) is still a bad trade in my book.

One sigil? When used once. In the course of an application one becomes
thousands.

Morevoer, it’s not a bad trade at all when you also consider colon to
colon syntax ugliness.

Of course, for people coming to Ruby via Rails, I can see the appeal of
making keyword args as easy to use as possible, since the Rails team
seems to have a real fetish for having single “do-it-all” methods that
dispatch based on an arbitrary number of optional keyword args.

Perhaps a little overdone, but it’s useful.

I’m not coming from Rails BTW. I’ve been here awhile.

T.


#12

Selon Daniel S. removed_email_address@domain.invalid:

pairs in a hash, where the key is a symbol (that seems to become the
norm). These should mean the same:

connect :to => “example.com
connect to: “example.com

And a normal hash:

{a: “foo”, b: “bar”, c: “baz”}
-> {:a => “foo”, :b => “bar”, :c => “baz”}

You don’t need the “should”. This very hash syntax has already been
adopted for
Ruby2 (http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l4). And I bet
it
influenced the current proposed syntax for named parameters. You can
immediately begin using methods that use hash arguments with the new
syntax,
and then slowly refactor to use true named parameters, without having
the
syntax changed.

Christophe G…

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.


#13

Christophe G. wrote:

the `key: value’ should be added as a generic way of writing key/value

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.

Jolly-good then!


#14

The reason I think symbols are appropriate as keys when calling a method
with named parameters is that I believe symbols are names.

Well, everything is a ‘name’ really. What these are first and formost
is parameters. As with any parameter, when assinging them via the
method interface one is actually assigning a local varaible --that
really has nothing to do with symbols. Symbols only need to come into
play when wants to collect an arbitrary set of named parameters. Just
as one needs an array to collect an arbitrary set of ordered
parameters, one needs a hash to collect an arbitrary set of named
parameters, and thus we need symbols for the hash keys. So the idea
that these are names, as you put, it is really secondary.

As for the definiton. If keyword parameters required a default value
then it is easy to decipher:

def grab( x from y=‘foo’ )

end

Anyway, it ws just a thought --It a nicer notation is all, and I
proposed it b/c before I hadn’t thought it possible, but realized that
in fact it may indeed be feasible.

T.