# Chapter 5Lexical variables

Scheme’s variables have lexical scope, ie, they are visible only to forms within a certain contiguous stretch of program text. The global variables we have seen thus far are no exception: Their scope is all program text, which is certainly contiguous.

We have also seen some examples of local variables. These were the `lambda` parameters, which get bound each time the procedure is called, and whose scope is that procedure’s body. Eg,

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

x        =>  9

x        =>  9
```

Here, there is a global `x`, and there is also a local `x`, the latter introduced by procedure `add2`. The global `x` is always `9`. The local `x` gets bound to `3` in the first call to `add2` and to the value of the global `x`, ie, `9`, in the second call to `add2`. When the procedure calls return, the global `x` continues to be `9`.

The form `set!` modifies the lexical binding of a variable.

```(set! x 20)
```

modifies the global binding of `x` from `9` to `20`, because that is the binding of `x` that is visible to `set!`. If the `set!` was inside `add2`’s body, it would have modified the local `x`:

```(define add2
(lambda (x)
(set! x (+ x 2))
x))
```

The `set!` here adds `2` to the local variable `x`, and the procedure returns this new value of the local `x`. (In terms of effect, this procedure is indistinguishable from the previous `add2`.) We can call `add2` on the global `x`, as before:

```(add2 x) =>  22
```

(Remember global `x` is now `20`, not `9`!)

The `set!` inside `add2` affects only the local variable used by `add2`. Although the local variable `x` got its binding from the global `x`, the latter is unaffected by the `set!` to the local `x`.

```x =>  20
```

Note that we had all this discussion because we used the same identifier for a local variable and a global variable. In any text, an identifier named `x` refers to the lexically closest variable named `x`. This will shadow any outer or global `x`’s. Eg, in `add2`, the parameter `x` shadows the global `x`.

A procedure’s body can access and modify variables in its surrounding scope provided the procedure’s parameters don’t shadow them. This can give some interesting programs. Eg,

```(define counter 0)

(define bump-counter
(lambda ()
(set! counter (+ counter 1))
counter))
```

The procedure `bump‑counter` is a zero-argument procedure (also called a thunk). It introduces no local variables, and thus cannot shadow anything. Each time it is called, it modifies the global variable `counter` — it increments it by 1 — and returns its current value. Here are some successive calls to `bump‑counter`:

```(bump-counter) =>  1
(bump-counter) =>  2
(bump-counter) =>  3
```

## 5.1  `let` and `let*`

Local variables can be introduced without explicitly creating a procedure. The special form `let` introduces a list of local variables for use within its body:

```(let ((x 1)
(y 2)
(z 3))
(list x y z))
=>  (1 2 3)
```

As with `lambda`, within the `let`-body, the local `x` (bound to `1`) shadows the global `x` (which is bound to `20`).

The local variable initializations — `x` to `1`; `y` to `2`; `z` to `3` — are not considered part of the `let` body. Therefore, a reference to `x` in the initialization will refer to the global, not the local `x`:

```(let ((x 1)
(y x))
(+ x y))
=>  21
```

This is because `x` is bound to `1`, and `y` is bound to the global `x`, which is `20`.

Sometimes, it is convenient to have `let`’s list of lexical variables be introduced in sequence, so that the initialization of a later variable occurs in the lexical scope of earlier variables. The form `let*` does this:

```(let* ((x 1)
(y x))
(+ x y))
=>  2
```

The `x` in `y`’s initialization refers to the `x` just above. The example is entirely equivalent to — and is in fact intended to be a convenient abbreviation for — the following program with nested `let`s:

```(let ((x 1))
(let ((y x))
(+ x y)))
=>  2
```

The values bound to lexical variables can be procedures:

```(let ((cons (lambda (x y) (+ x y))))
(cons 1 2))
=>  3
```

Inside this `let` body, the lexical variable `cons` adds its arguments. Outside, `cons` continues to create dotted pairs.

## 5.2  `fluid‑let`

A lexical variable is visible throughout its scope, provided it isn’t shadowed. Sometimes, it is helpful to temporarily set a lexical variable to a certain value. For this, we use the form `fluid‑let`.1

```(fluid-let ((counter 99))
(display (bump-counter)) (newline)
(display (bump-counter)) (newline)
(display (bump-counter)) (newline))
```

This looks similar to a `let`, but instead of shadowing the global variable `counter`, it temporarily sets it to `99` before continuing with the `fluid‑let` body. Thus the `display`s in the body produce

```100
101
102
```

After the `fluid‑let` expression has evaluated, the global `counter` reverts to the value it had before the `fluid‑let`.

```counter =>  3
```

Note that `fluid‑let` has an entirely different effect from `let`. `fluid‑let` does not introduce new lexical variables like `let` does. It modifies the bindings of existing lexical variables, and the modification ceases as soon as the `fluid‑let` does.

To drive home this point, consider the program

```(let ((counter 99))
(display (bump-counter)) (newline)
(display (bump-counter)) (newline)
(display (bump-counter)) (newline))
```

which substitutes `let` for `fluid‑let` in the previous example. The output is now

```4
5
6
```

Ie, the global `counter`, which is initially `3`, is updated by each call to `bump‑counter`. The new lexical variable `counter`, with its initialization of `99`, has no impact on the calls to `bump‑counter`, because although the calls to `bump‑counter` are within the scope of this local `counter`, the body of `bump‑counter` isn’t. The latter continues to refer to the global `counter`, whose final value is `6`.

```counter =>  6
```

1 `fluid‑let` is a nonstandard special form. See sec 8.3 for a definition of `fluid‑let` in Scheme.