So far, we've worked with many built-in Scheme procedures (like +, *, etc.), but we haven't seen how to define our own. Procedures are created with the lambda form. Here's a simple example:
> (lambda (x) (* x x))
#<procedure>
Evaluating a lambda
form gives us back a procedure object,
which we can treat like any other value.
Unlike the built-in procedures that we've been working with, though,
this procedure lacks something important--a name. The procedures
constructed with lambda are thus called "anonymous"; if we want to
apply them, we have to write out the lambda expression as the operator
of an application:
> ((lambda (x) (* x x)) 4)
16
How does this work? As we saw in previous sections, we evaluate an
application of a
procedure to some arguments by first evaluating both the operator
(which is (lambda (x) (* x x))
here) and the operands.
Our lambda expression evaluates to an (anonymous) procedure of one
argument, x, which returns the value of x squared.
Applied to the value 4, this procedure returns 16.
Naming procedures
It's impractical--though certainly not impossible--to write programs using only anonymous procedures. Even relatively simple programs would become unbearably complicated if we had to write lambda expressions for every operator, rather than using convenient names. Since procedures are values, we can gives names to them with define, just as we can any other value:
> (define square (lambda (x) (* x x)))
> (square (square 2))
16
Here, we define square
to mean the procedure
(lambda (x) (* x x))
. Once this is done, we can use
square as a procedure anywhere we like. Scheme makes
no distinction between built-in and newly-defined procedures, so
procedure definitions are a crucial way in which Scheme programmers
extend the language.
It's a bit clumsy to have to write
(define <name> (lambda (<arg> ...) ...))
every time
we want to write a procedure, so Scheme provides a shorthand. We
can also write our definition of square as follows:
(define (square x)
(* x x))
The general form of this shorthand is:
(define (<name> <arg> ...) <body>)
This definition is the same as the one with the explicit lambda expression, but it's a little quicker to type. You'll see this form of definition constantly in Scheme code.