💾 Archived View for danieljanus.pl › blog › en › 2010 › 05 › 04 › defnk › index.gmi captured on 2023-07-10 at 13:33:36. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2021-11-30)
-=-=-=-=-=-=-
There’s been an ongoing [1] debate [2] about how to pass optional named arguments to Clojure functions. One way to do this is the defnk [3] 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 [4] and Objective Caml [5]. 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?