racket/collects/scribblings/guide/lambda.scrbl
Matthew Flatt 8d61bb4c70 reference-manual work
svn: r6495
2007-06-06 01:13:51 +00:00

160 lines
4.2 KiB
Racket

#reader(lib "docreader.ss" "scribble")
@require[(lib "manual.ss" "scribble")]
@require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"]
@title[#:tag "guide:lambda"]{Procedures}
A @scheme[lambda] expression creates a procedure. In the simplest
case, a @scheme[lambda] expression has the form
@specform[
(lambda (arg-id ...)
body-expr ...+)
]
The @scheme[...+] in this syntactic sketch means ``one or more
repetitions of the preceeding element;'' that is, one or more
@scheme[_body-expr]s.
A @scheme[lambda] form with @math{n} @scheme[_arg-id]s accepts
@math{n} arguments:
@interaction[
((lambda (x) x)
1)
((lambda (x y) (+ x y))
1 2)
((lambda (x y) (+ x y))
1)
]
A @scheme[lambda] expression can also have the form
@specform[
(lambda rest-id
body-expr ...+)
]
That is, a @scheme[lambda] expression can have a single
@scheme[_rest-id] that is not surrounded by parentheses. The resulting
procedure accepts any number of arguments, and the arguments are put
into a list bound to @scheme[_rest-id].
@examples[
((lambda x x)
1 2 3)
((lambda x x))
((lambda x (car x))
1 2 3)
]
Combining thes two styles, a @scheme[lambda] expression can have the
form
@specform[
(lambda (arg-id ...+ . rest-id)
body-expr ...+)
]
The result is a procedure that requires at least as many arguments as
@scheme[_arg-id]s, and also accepts any number of additional
arguments.
@examples[
((lambda (a b . x) (cons (/ a b) x))
1 2 3 4)
((lambda (a b . x) (cons (/ a b) x))
1 2)
((lambda (a b . x) (cons (/ a b) x))
1)
]
Support for optional and keyword arguments lead to even more
possibilities:
@itemize{
@item{Instead of just an @scheme[_arg-id], an form argument can be
@scheme[[_arg-id _default-expr]], which means that the argument
is optional. When the argument is not supplied,
@scheme[_default-expr] produces the default value. The
@scheme[_default-expr] can refer to any preceding
@scheme[_arg-id], and every following @scheme[_arg-id] must
have a default as well.
@examples[
((lambda (x [y 5]) (list x y))
1 2)
((lambda (x [y 5]) (list x y))
1)
((lambda (x [y (+ x 1)]) (list x y))
1)
(lambda ([x 5] y) (list x y))
]}
@item{Instead of just an @scheme[_arg-id], an form argument can be
@scheme[(code:line _keyword _arg-id)], which indicates a
by-keyword argument instead of a by-position argument. The
position of the keyword--identifier pair in the argument list
does not matter for matching with arguments in an application,
because it will be matched to an argument value by keyword
insteda of by position.
@examples[
((lambda (x #:second y) (list x y))
1 #:second 2)
((lambda (x #:second y) (list x y))
#:second 2 1)
((lambda (#:second y x) (list x y))
1 #:second 2)
((lambda (x #:second y) (list x y))
1 2)
((lambda (x #:second y) (list x y))
#:second 2)
]}
@item{The previous two possibilities can be combined to specify a
by-keyword argument with a default value.
@examples[
((lambda (x #:second [y 5]) (list x y))
1 #:second 2)
((lambda (x #:second [y 5]) (list x y))
1)
]}
}
The @scheme[case-lambda] form creates a procedure that can have
completely different behaviors depending on the number of arguments
that are supplied. A case-lambda expression has the form
@specform[
(case-lambda
[formals body-expr ...+]
...)
]
where each @scheme[_formals _body-expr ...+] is anlogous to
@scheme[(lambda _formals _body-expr ...+)]. That is, a
@scheme[_formals] can be @scheme[(_arg-id ...)], @scheme[_rest-id], or
@scheme[(_arg-id ... . _rest-id)].
Applying a procedure produced by @scheme[case-lambda] is like applying
a @scheme[lambda] for the first case that matches the number of given
arguments.
@examples[
((case-lambda [() 10][(x y) (+ x y)])
1 2)
((case-lambda [() 10][(x y) (+ x y)]))
((case-lambda [() 10][(x y) (+ x y)])
1)
]
A @scheme[case-lambda] procedure cannot directly support optional or
keyword arguments.
@refdetails["mz:lambda"]{procedure expressions}