next up previous contents
Next: Data types Up: Scheme Tutorial Previous: Procedures   Contents

Imperative programming

Imperative programming means programming with side effects. Scheme being a semi-functional language (meaning not completely functional) supports imperative programming style as well as functional. The assignment operator in Scheme is set!, which is a special form and has the following syntax:

(set! var expr)

The expr is evaluated and its value is bound to var. This is done as a side effect--the value of the set! expression itself is unspecified!

The set! expression does not create new bindings like define, it only changes existing bindings. The var in the set! expression must therefore be bound before set! is applied.

For example, let's try to assign the value 10 to a using set! without binding a first.

> (set! a 10)
set!: cannot set undefined identifier: a

This clearly did not work, so let's use define instead.

> (define a 10)
> a
10

Now, a is bound and everything is fine. We then want to change the value of a to 5 for some reason, so we use set! to accomplish our task.

> (set! a 5)
> a
5

Why cant we just use define instead of set! for this? Clearly,

> (define a 5)
> a
5

would have the same effect! In this case we could have used define instead, but the example above is not really from the real world. Definitions are valid only at the beginning of a body and at the top level of a program. At the top level, set! expressions are equivalent to definitions as long as the variable var is bound.

Let's look at another (unrealistic) example: we have a procedure sq! which takes one argument and sets the global variable a to the square of the argument.

(define a 0)

(define sq!
  (lambda (x)
    (set! a (square x))))

(define square
  (lambda (x)
    (* x x)))

> (sq! 10)
> a
100

What would have happened if we had tried to use define instead of set!? Let's try to feed the interpreter with the version using define:

(define sq!
  (lambda (x)
    (define a (square x))))

> define-values: illegal use (not at top-level) in: (#%define-values (a) 
(square x))

Oops! This was clearly illegal!

It is a convention in Scheme to name procedures causing mutations with a !, as in set! and sq!.


next up previous contents
Next: Data types Up: Scheme Tutorial Previous: Procedures   Contents
Timo Lilja 2001-09-11