# MUTATIVE PROGRAMMING

The functions we have designed returns the same value for same argument values, no matter what. But many real world programs need to remember values from their past uses. In other worlds the computational process has a "state", and the return value of some functions may depend on the state of the process as well as on their inputs.

The programs we have written so far did not leave any traces of their work in the state of the process. Once we start writing programs which instead leave such traces, we enter the realm of "mutative programming". Mutative functions do not only compute an output value, but also cause a permanent change in the state of the process, which effect how the same -or another- function will work when called afterwards. In other words mutative functions do not only compute a result value but also cause "side effects" in the state of the world/process.

## Example: traffic lights

Traffic lights change their color when a timer triggers them. However the next color of the traffic light depends on what was its color before. As a consequence we are presented with a stateful problem.

## Assignment to variables

The way to represent -and mutate- the state of the process is to store the state in variables. A variable is a storage box in the memory to store a value. One can change the value in the box when desired, thus the name "variable".

We have actually declared such variables, but not yet "varied" them. The `set!` command in Racket is used to update/vary such variables. It is a very different command than we have learned before because it does not return anything! Instead it changes a variable, i.e. its purpose is not to produce an output, but to change the process state:

``````    > (define x 0)
> x
0
> (set! x 1)
(void)
> x
1
> (set! x (+ x 1))
(void)
> x
2
> ``````

Note that `set!` command returns `void`, that is it returns nothing.

## Solution: Traffic lights

The mutative solution to traffic lights problem is below.

``````    (define light "red")

(define (next)
(cond
((string=? light "red") (set! light "yellow"))
((string=? light "yellow") (set! light "green"))
(else (set! light "red"))))``````

Now, run the program then use the interpreter screen to execute `next` function several times:

``````    > (next)
(void)
> light
"yellow"
> next
next
> (next)
(void)
> light
"green"
> ``````

Note that the function we have written has not input parameters. Its input is the value of a variable, ie. its input is the current state of the process. It also has no return value, it does its job by changing/varying a variable.

## Sequencing commands

We often encounter a situation in which we need to both change a variable and return a value from a function. This means our function needs to do two independent actions. This is a situation we have never seen before. All functions we have written, simple or complex, contained a single expression: arithmetic or conditional, or both, or several of both nested inside. To manage with this new situation we will use another special command `(begin ...)`. This command can encapsulate several commands in a sequence, and returns the outcome of the last command as its return value. We will replace the next function as follows:

``````    (define light "red")

(define (next)
(begin
(cond
((string=? light "red") (set! light "yellow"))
((string=? light "yellow") (set! light "green"))
(else (set! light "red")))
light))``````

This version of the `next` function first executes a conditional statement, then the `light` as the last entity in `(begin ...)` sequence is returned as its return value. Now try executing the next command, it returns the most recent value of `light` variable instead of `void`:

``````    > (next)
"yellow"
> (next)
"green"
> (next)
"red"
> (next)
"yellow"
> ``````

## Example problem: Managing address book

``````    (define-struct Address (name phone))

Now update the address book using interactive pane:

``````    > addressBook
empty
(void)
Write a function to find a phone number of person whose name is given, in the address book (note you don't need to use `set!` or `begin` or any of the new techniques to do that).