Tue, 04 May 2010
Keyword arguments
There’s been an ongoing debate about how to pass optional named
arguments to Clojure functions. One way to do this is the defnk
macro from clojure.contrib.def; I hesitate to call it canonical,
since apparently not everyone uses it, but I’ve found it useful a
number of times. Here’s a sample:
user> (use 'clojure.contrib.def)
nil
user> (defnk f [:b 43] (inc b))
#'user/f
user> (f)
44
user> (f :b 100)
101
This is an example of keyword arguments in action. Keyword arguments
are a core feature of some languages, notably Common Lisp and
Objective Caml. Clojure doesn’t have them, but it’s pretty easy to
emulate their basic usage with macros, as defnk does.
But there’s more to Common Lisp’s keyword arguments than defnk
provides. In CL, the default value of a keyword argument can be an
expression referring to other arguments of the same function. For
example:
CL-USER> (defun f (&key (a 1) (b a))
(+ a b))
F
CL-USER> (f)
2
CL-USER> (f :a 45)
90
CL-USER> (f :b 101)
102
I wish defnk had this feature. Or is there some better way that I
don’t know of?