Next: , Up: Optional Arguments


6.9.4.1 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])
body

     
     
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.