Procedures are first class in Scheme, meaning that procedures can be assigned to variables, passed as arguments to other procedures, be returned from procedures, and be applied to arbitrary arguments. When they are created, procedures ``capture'' variables that are free in their bodies. Because of this ``closing over,'' procedures are also known as closures in Scheme.
Closures can be used for a wide variety of purposes. They can be used to represent objects in an object-oriented framework, to model actors, to represent partially computed solutions, etc.
Unnamed procedures are created with the
lambda special form.
The existence of unnamed procedures frees the programmer from making
up names for simple helper functions. For example, many Scheme
implementations have a
sort procedure that accepts a list or
vector of elements, and a comparison procedure that is used to
establish an ordering on the elements. It is often useful to use an
unnamed procedure as the comparison function:
> (sort '(1 6 3 4) (lambda (n1 n2) (< n1 n2))) (1 3 4 6) > (sort #("jim" "brent" "jason" "todd") (lambda (s1 s2) (string<? s1 s2))) #("brent" "jason" "jim" "todd")
(1 2 3 4) is a list of numbers and
#("jim" ...) is a vector of strings.
The next example shows the definition of a procedure
make-counter that returns another procedure created with
lambda that closes over the
> (define (make-counter) (let ((count 0)) (lambda () (set! count (+ count 1)) count))) make-counter > (define c1 (make-counter)) c1 > (c1) 1 > (c1) 2
Since no one else has access to
count it becomes private to the
closure and can be modified and used within its context. In this
count is incremented and its value returned
when the procedure returned from
make-counter is called.