A lambda expression evaluates to a procedure. STklos lambda expression
have been extended to allow a optional and keyword parameters.
<formals> should have one of the following forms:
(<variable1> ...) : The procedure takes a fixed number of arguments;
when the procedure is called, the arguments will be stored in the
bindings of the corresponding variables. This form is identical to
R5RS
.
<variable> : The procedure takes any number of arguments; when the
procedure is called, the sequence of actual arguments is converted into
a newly allocated list, and the list is stored in the binding of the
<variable> . This form is identical to R5RS
.
(<variable1> ... <variablen> . <variablen+1>) : If a space-delimited
period precedes the last variable, then the procedure takes n or more
arguments, where n is the number of formal arguments before the period
(there must be at least one). The value stored in the binding of the
last variable will be a newly allocated list of the actual arguments left
over after all the other actual arguments have been matched up against
the other formal arguments. This form is identical to R5RS
.
(<variable1 ... <variablen> [:optional ...] [:rest ...] [:key ...])
This form is specific to STKLOS and allows to have procedure with
optional and keyword parameters. The form :optional allows to specify
optional parameters. All the parameters specified after :optional to the end
of <formals> (or until a :rest or :key ) are optional parameters. An
optional parameter can declared as:
variable : if a value is passed when the procedure is called, it will be
stored in the binding of the corresponding variable, otherwise the value #f
will be stored in it.
(variable value) : if a value is passed when the procedure is called, it
will be stored in the binding of the corresponding variable, otherwise value
will be stored in it.
(variable value test?) : if a value is passed when the procedure is called, it
will be stored in the binding of the corresponding variable, otherwise value
will be stored in it. Furthermore, test? will be given the value #t if
a value is passed for the given variable, otherwise test? is set to #f
Hereafter are some examples using :optional parameters
((lambda (a b :optional c d) (list a b c d)) 1 2)
=> (1 2 #f #f)
((lambda (a b :optional c d) (list a b c d)) 1 2 3)
=> (1 2 3 #f)
((lambda (a b :optional c (d 100)) (list a b c d)) 1 2 3)
=> (1 2 3 100)
((lambda (a b :optional c (d #f d?)) (list a b c d d?)) 1 2 3)
=> (1 2 3 #f #f)
The form :rest parameter is similar to the dot notation seen before.
It is used before an identifier to collects the parameters in a single
binding:
((lambda (a :rest b) (list a b)) 1)
=> (1 ())
((lambda (a :rest b) (list a b)) 1 2)
=> (1 (2))
((lambda (a :rest b) (list a b)) 1 2 3)
=> (1 (2 3))
The form :key allows to use keyword parameter passing. All the parameters
specified after :key to the end of <formals> are keyword parameters. A
keyword parameter can be declared using the three forms given for optional
parameters. Here are some examples illustrating how to declare and how to use
keyword parameters:
((lambda (a :key b c) (list a b c)) 1 :c 2 :b 3)
=> (1 3 2)
((lambda (a :key b c) (list a b c)) 1 :c 2)
=> (1 #f 2)
((lambda (a :key (b 100 b?) c) (list a b c b?)) 1 :c 2)
=> (1 100 2 #f)
At last, here is an example showing :optional :rest and :key parameters
(define f (lambda (a :optional b :rest c :key d e)
(list a b c d e)))
(f 1) => (1 #f () #f #f)
(f 1 2) => (1 2 () #f #f)
(f 1 2 :d 3 :e 4) => (1 2 (:d 3 :e 4) 3 4)
(f 1 :d 3 :e 4) => (1 #f (:d 3 :e 4) 3 4)
|