Scheme Programming/Procedures

Scheme Programming
 ← Conditionals Procedures Looping → 

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 proceduresEdit

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.