lambda* and define*.
lambda* is like lambda, except with some extensions to allow optional and keyword arguments.
library syntax: lambda* `([var…] [#:optional vardef…] [#:key vardef… [#:allow-other-keys]] [#:rest var | . var])
body1 body2 …`
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.