Arc Forumnew | comments | leaders | submitlogin
1 point by aston 6122 days ago | link | parent

Hmm. Allowing keyword args is pretty un-Arc-ish (is there a term for this yet?) in my eyes. Lots of extra tokens to specify keywords when you could've just used positional arguments with some optional args at the end.


10 points by bogomipz 6122 days ago | link

Keyword arguments definitely have their place. They fix a problem with having too many optional args. Example:

  (def foo (a b c (o d) (o e) (o f) (o g))
If you want to call foo with g but not the other optional args, you'd have to write

  (foo 1 2 3 nil nil nil 42)
It's easy to loose track of positional args when there are more than say 5 of them (depends on the person), and it gets a lot worse when some are just nils. The above call with keyword args instead of optionals would be something like;

  (foo 1 2 3 'g 42)
Or, depending on the implementation, there might be a special syntax;

  (foo 1 2 3 :g 42)

-----

3 points by aston 6122 days ago | link

I think there are two distinct cases here. The first is when a procedure is taking a number of options/switches. The second is when the function has a long list of optional arguments.

I actually think the second is pretty rare, especially if the argument list is ordered by practical use. The first is handled pretty nicely by passing in association lists or hash tables. Of course, the current syntax for creating hash tables doesn't make using them as arguments super-easy, but they're the equivalent of passing a dictionary in python for kwargs, and they don't require any new syntax.

edit: In my imagined world, your last example would look something like

  (foo 1 2 3 (table g 42))
where table could take kv's ad infinitum.

-----

2 points by bogomipz 6122 days ago | link

I don't see the distinction between taking a number of options and having a number of optional arguments. To me, this is exactly the same. A switch is an argument that is only checked for true/false, which means that in ordinary function calls you only really want to bother with it when passing 't.

It's true that passing a data structure can do most of the job of keyword arguments. Any searchable structure will do, really. Perhaps the simplest form from the call site's point of view is a property list. If Scheme's plist-get was implemented in Arc (trivial, but pg would probably pick a shorter name):

  (def foo (a b c . rest)
    (plist-get rest 'g))

  arc> (foo 1 2 3 'g 42)
  42
So, what do keyword arguments give you that tables/alists/plists do not?

1) better self documentation - the function signature tells what keys it understands

2) less code in the function body - you access the value like any other argument

3) a default form which is only evaluated if no value was given - without adding code to the function body

-----

1 point by sjs 6121 days ago | link

How about something like this:

  (def kw args
    (listtab (pair args)))
That makes it pretty easy to pass around kw args, and with a macro you could make it a little more sugary by allowing unquoted keys.

-----