lambda*
is like lambda
, except with some extensions to
allow optional and keyword arguments.
Create a procedure which takes optional and/or keyword arguments
specified with #:optional
and #: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 #f
.
Likewise, define*
is syntactic sugar for defining procedures
using lambda*
.
lambda*
can also make procedures with keyword arguments. For
example, a procedure defined like this:
(define* (sir-yes-sir #:key action how-high) (list action how-high))
can be called as (sir-yes-sir #:action 'jump)
,
(sir-yes-sir #:how-high 13)
, (sir-yes-sir #:action
'lay-down #:how-high 0)
, or just (sir-yes-sir)
. Whichever
arguments are given as keywords are bound to values (and those not
given are #f
).
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
(define* (frob 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-keys
to 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,
(define* (flips #:key (heads 0) (tails 0)) (display (list heads tails))) (flips #:heads 37 #:tails 42 #:heads 99) -| (99 42)
#:rest
is 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.
When #:key
is 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)
#:optional
and #:key
establish their bindings
successively, from left to right. 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)))
The exception to this left-to-right scoping rule is the rest argument. If there is a rest argument, it is bound after the optional arguments, but before the keyword arguments.