Daniel Janus’s blog
Keyword arguments
4 May 2010
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?