Node:lambda* Reference, Next:, Previous:let-keywords Reference, Up:Optional Arguments

23.2.3 lambda* Reference

When using optional and keyword argument lists, using lambda for creating procedures and using let-optional or let-keywords is a bit lengthy. Therefore, lambda* is provided, which combines the features of those macros into a single convenient syntax.

For quick reference, here is the syntax of the formal argument list for lambda* (brackets are used to indicate grouping only):

ext-param-list ::= [identifier]* [#:optional [ext-var-decl]+]?
  [#:key [ext-var-decl]+ [#:allow-other-keys]?]?
  [[#:rest identifier]|[. identifier]]?

ext-var-decl ::= identifier | ( identifier expression )

The characters `*', `+' and `?' are not to be taken literally; they mean respectively, zero or more occurrences, one or more occurrences, and one or zero occurrences.

lambda* formals body library syntax
lambda* creates a procedure that takes optional arguments. These are specified by putting them inside brackets at the end of the parameter list, but before any dotted rest argument. For example,
(lambda* (a b #:optional c d . e) '())

creates 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.

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 (#:xyzzy 11) (#:larch 13) (#:larch 42 #:xyzzy 19) (). Whichever arguments are given as keywords are bound to values.

Optional and keyword arguments can also be given default values which they take on when they are not present in a call, by giving a two-item list in place of an optional argument, 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.

lambda* also supports two more special parameter list keywords.

lambda*-defined procedures now throw an error by default if a keyword other than one of those specified is found in the actual passed arguments. However, specifying #:allow-other-keys immediately after the keyword argument declarations restores the previous behavior of ignoring unknown keywords. lambda* also now guarantees that if the same keyword is passed more than once, the last one passed is the one that takes effect. For example,

((lambda* (#:key (heads 0) (tails 0)) (display (list heads tails)))
    #:heads 37 #:tails 42 #:heads 99)

would result in (99 47) being displayed.

#:rest is also now provided as a synonym for the dotted syntax rest argument. The argument lists (a . b) and (a #:rest b) are equivalent in all respects to lambda*. This is provided for more similarity to DSSSL, MIT-Scheme and Kawa among others, as well as for refugees from other Lisp dialects.