#
Chapter 3
Forms

The reader will have noted that the Scheme example programs provided thus far are also s-expressions. This is true of all Scheme programs: Programs are data.

Thus, the character datum `#\c` is a program, or a form. We will use the more general term form instead of program, so that we can deal with program fragments too.

Scheme evaluates the form `#\c` to the value `#\c`, because `#\c` is self-evaluating. Not all s-expressions are self-evaluating. For instance the symbol s-expression `xyz` evaluates to the value held by the variable `xyz`. The list s-expression `(string->number "16")` evaluates to the number 16.

Not all s-expressions are valid programs. If you typed the dotted-pair s-expression `(1 . 2)` at the Scheme listener, you will get an error.

Scheme evaluates a list form by examining the first element, or head, of the form. If the head evaluates to a procedure, the rest of the form is evaluated to get the procedure's arguments, and the procedure is applied to the arguments.

If the head of the form is a special form, the evaluation proceeds in a manner idiosyncratic to that form. Some special forms we have already seen are `begin`, `define`, and `set!`. `begin` causes its subforms to be evaluated in order, the result of the entire form being the result of the last subform. `define` introduces and initializes a variable. `set!` changes the binding of a variable.

## 3.1 Procedures

We have seen quite a few primitive Scheme procedures, eg, `cons`, `string->list`, and the like. Users can create their own procedures using the special form `lambda`. For example, the following defines a procedure that adds `2` to its argument:

    (lambda (x) (+ x 2))

The first subform, `(x)`, is the list of parameters. The remaining subform(s) constitute the procedure's body. This procedure can be called on an argument, just like a primitive procedure:

    ((lambda (x) (+ x 2)) 5)
    =>  7

If we wanted to call this same procedure many times, we could create a replica using `lambda` each time, but we can do better. We can use a variable to hold the procedure value:

    (define add2
      (lambda (x) (+ x 2)))

We can then use the variable `add2` each time we need a procedure for adding `2` to its argument:

    (add2 4) =>  6
    (add2 9) =>  11

### 3.1.1 Procedure parameters

The parameters of a `lambda`-procedure are specified by its first subform (the form immediately following the head, the symbol `lambda`). `add2` is a single-argument -- or unary -- procedure, and so its parameter list is the singleton list `(x)`. The symbol `x` acts as a variable holding the procedure's argument. Each occurrence of `x` in the procedure's body refers to the procedure's argument. The variable `x` is said to be local to the procedure's body.

We can use 2-element lists for 2-argument procedures, and in general, n-element lists for n-argument procedures. The following is a 2-argument procedure that calculates the area of a rectangle. Its two arguments are the length and breadth of the rectangle.

    (define area
      (lambda (length breadth)
        (* length breadth)))

Notice that `area` multiplies its arguments, and so does the primitive procedure `*`. We could have simply said:

    (define area *)

### 3.1.2 Variable number of arguments

Some procedures can be called at different times with different numbers of arguments. To do this, the `lambda` parameter list is replaced by a single symbol. This symbol acts as a variable that is bound to the list of the arguments that the procedure is called on.

In general, the `lambda` parameter list can be a list of the form `(x ...)`, a symbol, or a dotted pair of the form `(x ... . z)`. In the dotted-pair case, all the variables before the dot are bound to the corresponding arguments in the procedure call, with the single variable after the dot picking up all the remaining arguments as one list.

## 3.2 `apply`

The Scheme procedure `apply` lets us call a procedure on a list of its arguments.

    (define x '(1 2 3))

    (apply + x)
    =>  6

In general, `apply` takes a procedure, followed by a variable number of other arguments, the last of which must be a list. It constructs the argument list by prefixing the last argument with all the other (intervening) arguments. It then returns the result of calling the procedure on this argument list. Eg,

    (apply + 1 2 3 x)
    =>  12

## 3.3 Sequencing

We used the `begin` special form to bunch together a group of subforms that need to be evaluated in sequence. Many Scheme forms have implicit `begin`s. For example, let's define a 3-argument procedure that displays its three arguments, with spaces between them. A possible definition is:

    (define display3
      (lambda (arg1 arg2 arg3)
        (begin
          (display arg1)
          (display " ")
          (display arg2)
          (display " ")
          (display arg3)
          (newline))))

In Scheme, `lambda`-bodies are implicit `begin`s. Thus, the `begin` in `display3`'s body isn't needed, although it doesn't hurt. `display3`, more simply, is:

    (define display3
      (lambda (arg1 arg2 arg3)
        (display arg1)
        (display " ")
        (display arg2)
        (display " ")
        (display arg3)
        (newline)))