When using optional and keyword argument lists,
creating a procedure then
is a bit lengthy.
lambda* combines the features of those
macros into a single convenient syntax.
Create a procedure which takes optional and/or keyword arguments specified with
#:key. For example,(lambda* (a b #:optional c d . e) '())
is a procedure with fixed arguments a and b, optional arguments c and d, and rest argument e. If the optional arguments are omitted in a call, the variables for them are bound to
lambda*can also take keyword arguments. For example, a procedure defined like this:(lambda* (#:key xyzzy larch) '())
can be called with any of the argument lists
(#:larch 42 #:xyzzy 19),
(). Whichever arguments are given as keywords are bound to values (and those not given are
Optional and keyword arguments can also have default values to take when not present in a call, by giving a two-element list of variable name and expression. For example in(lambda* (foo #:optional (bar 42) #:key (baz 73)) (list foo bar baz))
foo is a fixed argument, bar is an optional argument with default value 42, and baz is a keyword argument with default value 73. Default value expressions are not evaluated unless they are needed, and until the procedure is called.
Normally it's an error if a call has keywords other than those specified by
#:key, but adding
#:allow-other-keysto the definition (after the keyword argument declarations) will ignore unknown keywords.
If a call has a keyword given twice, the last value is used. For example,((lambda* (#:key (heads 0) (tails 0)) (display (list heads tails))) #:heads 37 #:tails 42 #:heads 99) -| (99 42)
#:restis a synonym for the dotted syntax rest argument. The argument lists
(a . b)and
(a #:rest b)are equivalent in all respects. This is provided for more similarity to DSSSL, MIT-Scheme and Kawa among others, as well as for refugees from other Lisp dialects.
#:keyis used together with a rest argument, the keyword parameters in a call all remain in the rest list. This is the same as Common Lisp. For example,((lambda* (#:key (x 0) #:allow-other-keys #:rest r) (display r)) #:x 123 #:y 456) -| (#:x 123 #:y 456)
#:keyestablish their bindings successively, from left to right, as per
let-keywords*. This means default expressions can refer back to prior parameters, for example(lambda* (start #:optional (end (+ 10 start))) (do ((i start (1+ i))) ((> i end)) (display i)))