Keyword arguments like grandma makes 'em

Discussion in 'Ruby' started by Trans, Nov 17, 2005.

  1. Trans

    Trans Guest

    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.
    Trans, Nov 17, 2005
    #1
    1. Advertising

  2. Selon Trans <>:

    > 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 =3D> '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.
    >


    Congratulations, you've just reinvented Smalltalk ;) (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 f=
    ind
    named parameters cool or annoying :) . 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 a=
    nother
    question though.
    --
    Christophe Grandsire.

    http://rainbow.conlang.free.fr

    It takes a straight mind to create a twisted conlang.
    Christophe Grandsire, Nov 17, 2005
    #2
    1. Advertising

  3. Trans

    rj-cole Guest

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

    regards,

    Richard.
    rj-cole, Nov 17, 2005
    #3
  4. Trans

    rj-cole Guest

    Sorry I made a typo, I meant *worth* reading, not work reading.
    rj-cole, Nov 17, 2005
    #4
  5. Trans

    Trans Guest

    > Without trying to get personal or offensive, I'd recommend you
    > to try to implement your ideas at first. ;-)


    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.
    Trans, Nov 17, 2005
    #5
  6. Trans

    rcoder Guest

    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
    rcoder, Nov 18, 2005
    #6
  7. Trans

    Trans Guest

    rcoder wrote:
    > 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.


    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.
    Trans, Nov 18, 2005
    #7
  8. Trans

    rcoder Guest

    > 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
    rcoder, Nov 18, 2005
    #8
  9. Trans

    Trans Guest

    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.
    Trans, Nov 18, 2005
    #9
  10. rj-cole wrote:
    > 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 :)
    >
    > 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 method `foo', setting the parameter named `bar' to the
    value of `baz' (even though I think the `=>' operator actually means
    "points to").

    This won't disallow for Matz' `foo bar: "baz"' style. Actually, I think
    the `key: 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
    Daniel Schierbeck, Nov 18, 2005
    #10
  11. Selon Daniel Schierbeck <>:

    >
    > The reason I think symbols are appropriate as keys when calling a metho=

    d
    > with named parameters is that I believe symbols are *names*. Names of
    > method, variables, attributes, etc. So when I type `foo :bar =3D> "baz"=

    ',
    > I'm calling the method `foo', setting the parameter named `bar' to the
    > value of `baz' (even though I think the `=3D>' operator actually means
    > "points to").
    >
    > This won't disallow for Matz' `foo bar: "baz"' style. Actually, I think
    > the `key: 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 =3D> "example.com"
    > connect to: "example.com"
    >
    > And a normal hash:
    >
    > {a: "foo", b: "bar", c: "baz"}
    > -> {:a =3D> "foo", :b =3D> "bar", :c =3D> "baz"}
    >


    You don't need the "should". This very hash syntax has already been adopt=
    ed for
    Ruby2 (http://eigenclass.org/hiki.rb?Changes in Ruby 1.9#l4). And I bet i=
    t
    influenced the current proposed syntax for named parameters. You can
    immediately begin using methods that use hash arguments with the new synt=
    ax,
    and then slowly refactor to use true named parameters, without having the
    syntax changed.
    --
    Christophe Grandsire.

    http://rainbow.conlang.free.fr

    It takes a straight mind to create a twisted conlang.
    Christophe Grandsire, Nov 18, 2005
    #11
  12. Christophe Grandsire wrote:
    > Selon Daniel Schierbeck <>:
    >
    >> 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 method `foo', setting the parameter named `bar' to the
    >> value of `baz' (even though I think the `=>' operator actually means
    >> "points to").
    >>
    >> This won't disallow for Matz' `foo bar: "baz"' style. Actually, I think
    >> the `key: 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"}
    >>

    >
    > 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 Grandsire.
    >
    > http://rainbow.conlang.free.fr
    >
    > It takes a straight mind to create a twisted conlang.
    >
    >

    Jolly-good then!
    Daniel Schierbeck, Nov 18, 2005
    #12
  13. Trans

    Trans Guest

    > 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.
    Trans, Nov 18, 2005
    #13
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Edward Diener
    Replies:
    14
    Views:
    4,855
    Josiah Carlson
    Apr 6, 2004
  2. Houston Barnett-gearhart

    deaf grandma.

    Houston Barnett-gearhart, Jul 27, 2008, in forum: Ruby
    Replies:
    23
    Views:
    261
    Dave Lilley
    Mar 19, 2009
  3. Phee Luche
    Replies:
    6
    Views:
    175
    Simon Anker
    Jul 31, 2008
  4. Bianca George

    One more Deaf Grandma topic

    Bianca George, Aug 19, 2008, in forum: Ruby
    Replies:
    3
    Views:
    194
    Adam Shelly
    Aug 21, 2008
  5. danielj

    Deaf Grandma

    danielj, Aug 27, 2008, in forum: Ruby
    Replies:
    10
    Views:
    193
    Steve K.
    May 4, 2011
Loading...

Share This Page