Arc Forumnew | comments | leaders | submitlogin
How do you use keyword parameters in Arc?
3 points by lark 3982 days ago | 4 comments
Is there such a thing as keyword parameters in Arc or a way to add them easily?


3 points by zck 3981 days ago | link

Well, it depends if you're talking vanilla Arc, or a different implementation.

If you want to go with base Arc, you can pass a dictionary in, something like this:

  (def greet ((o arg-dict (obj)))
       (prn "Hello there, "
            (or arg-dict!person "friend")
            "! Would you like "
            (or arg-dict!thing-to-offer "some ice cream")
            "?"))
  
  arc> (greet)
  Hello there, friend! Would you like some ice cream?
  "Hello there, "
  arc> (greet (obj person "Darth Vader" thing-to-offer "a lightsaber"))
  Hello there, Darth Vader! Would you like a lightsaber?
  "Hello there, "
  arc> (greet (obj thing-to-offer "two lightsabers"))
  Hello there, friend! Would you like two lightsabers?
  "Hello there, "
  arc> 
You could, I suppose, treat a rest argument as a list of (keyword argument) pairs:

  (def greet2 arg-list
       (let args (pair arg-list)
            (prn "Hello there, "
                 (or (alref args 'person) "friend")
                 "! Would you like "
                 (or (alref args 'thing-to-offer) "some ice cream")
                 "?")))
  
  arc> (greet2)
  Hello there, friend! Would you like some ice cream?
  "Hello there, "
  arc> (greet2 'person "Darth Vader" 'thing-to-offer "a lightsaber")
  Hello there, Darth Vader! Would you like a lightsaber?
  "Hello there, "
  arc> (greet2 'thing-to-offer "two lightsabers")
  Hello there, friend! Would you like two lightsabers?
  "Hello there, "
  arc> 
Note: this has no error checking, but the failure mode isn't awful:

  arc> (greet2 'person)
  Hello there, friend! Would you like some ice cream?
  "Hello there, "
  arc> 
You can mix this with required parameters:

  (def greet3 (emotion . arg-list)
       (let args (pair arg-list)
            (prn "Hello there, "
                 (or (alref args 'person) "friend")
                 "! I'm " 
                 emotion
                 " to see you. Would you like "
                 (or (alref args 'thing-to-offer) "some ice cream")
                 "?")))
  arc> (greet3 'happy)
  Hello there, friend! I'm happy to see you. Would you like some ice cream?
  "Hello there, "
  arc> (greet3 'enraged 'thing-to-offer "to be murdered")
  Hello there, friend! I'm enraged to see you. Would you like to be murdered?
  "Hello there, "
  arc> 
I haven't used these; I've merely come up with them on the spot. No doubt other people have come up with better ideas.

Downsides include not having a good way to set defaults -- you have to supply the default each time in the code you use it. Alternately, you can put the body in a function that requires each argument, then in the "regular" function, supply the default as an argument to the helper:

  (def greet4 (emotion . arg-list)
       (let args (pair arg-list)
            (greet4-helper emotion
                           (or (alref args 'person)
                               "friend")
                           (or (alref args 'thing-to-offer)
                               "some ice cream"))))
  
  (def greet4-helper (emotion person thing-to-offer)
       (prn "Hello there, "
            person
            "! I'm " 
            emotion
            " to see you. Would you like "
            thing-to-offer
            "?"))
  
  arc> (greet4 'bored)
  Hello there, friend! I'm bored to see you. Would you like some ice cream?
  "Hello there, "
  arc> (greet4 'bored 'thing-to-offer "to go away")
  Hello there, friend! I'm bored to see you. Would you like to go away?
  "Hello there, "
  arc> 
Note that you can't explicitly pass nil this way:

  arc> (greet4 'bored 'thing-to-offer nil)
  Hello there, friend! I'm bored to see you. Would you like some ice cream?
  "Hello there, "
  arc>

-----

1 point by lark 3981 days ago | link

Thanks for the cool tricks. These will work.

-----

1 point by Pauan 3981 days ago | link

"[...] or a way to add them easily?"

Arc/Nu used to have keyword arguments, but they were a pain in the butt to implement, and only a single function actually used them, so I took them out.

So, it's possible, yes, but not easy. At least, not easy using Racket's keyword arguments. It might be easier if I did everything from scratch...

-----

1 point by akkartik 3981 days ago | link

I've been maintaining a fork with keyword args: http://github.com/akkartik/arc. Wart has them as well.

-----