Defining the

The "

Suppose we wanted to find the average of a list of numbers. In Scheme it is best to write a program using quite small functions. It is worth remembering that any loop in an imperative language translates into a recursive function in Scheme - so two nested loops translate into two functions.

The average is the sum of the numbers in the list divided by how many numbers there are in the list. We could define it by:

```
(define (average list)
(/ (sum list) (length list)))
```

When we compile this function, Scheme responds:

DECLARING VAR sum

This indicates to you that Scheme does *not*
know about the function `sum` that you have called, so you will
have to define it.

It also indicates that Scheme *does* know about the function
`length`. So you had better check if the built-in function
'`length`' does the right thing. You can redefine built-in functions
in Scheme, but it is not a good idea. (Actually `length` does just
what we want). Try it!

```
(length '(the fat cat eats the thin canary))
```

evaluates to 7.

If we try running `average`, you will get an error-message,
identifying '`sum`' as the culprit:

```
(average '(1 2 3))
```

Error: Cannot apply object Uninitialised variable 'sum as function In file: /users/users3/fac/pop/poplocal/local/Scheme/lecture4.scm Value = 1 This error report was prepared for Robin Popplestone by Jeremiah Jolt, your compile-time helper.

We can now mend our program.

```
(define (sum list)
(if (null? list)
0
(+ (car list) (sum (cdr list)))))
```

And try `sum`

```
(sum '(1 2 3))
```

```
6
```

Finally evaluating

```
(average '(1 2 3))
```

yields:

```
2
```

while:

```
(average '(1 2 3 4))
```

evaluates to the rational number:

```
5/2
```

So perhaps it is better to do

```
(average '(1.0 2.0 3.0 4.0))
```

```
2.5
```

In the last example we made a simple number from a list, using `car`
and `cdr` to explore the list. In this example we build a new list.

Suppose we want to take a list of numbers and replace each number in the list by a number twice as big. We could do it something like this:

```
(define (double_list l)
(if (null? l)
'()
(cons (* (car l) 2) (double_list (cdr l)))))
```

Trying this out:

```
(double_list '(22 33 44))
```

```
(44 66 88)
```

How could we make this more general? Suppose we wanted to multiply by
*any*
number? We could replace the constant 2 by a parameter. This is called
abstraction.

```
(define (multiple-list n l)
(if (null? l)
'()
(cons (* (car l) n) (multiple-list n (cdr l)))))
```

(multiple-list 10 '(5 6 7))
(50 60 70)
Suppose we then wanted to

```
(define (sqrt_list l)
(if (null? l)
'()
(cons (sqrt (car l)) (sqrt_list (cdr l)))))
```

```
(sqrt_list '(4 100 16))
```

```
(2 10 4)
```

Look at what we are doing here - we are applying a function,
` sqrt ` ,
to every member of the list. Can we generalise this idea?
This depends on an important property of Scheme - * we can pass
functions as arguments to other functions*. So: we can replace the call
of ` sqrt `
in `sqrt_list` by a call of ` f ` , where
` f `
is an argument of a new function I shall call `map_list`.

```
(define map_list
(lambda (f l)
(if (null? l)
'()
(cons
(f (car l))
(map_list f (cdr l))
)
); end if
) ; end lambda
) ; end define
```

Using `map_list`
we can take the square-root of a list of functions quite
easily:

(map_list sqrt '(4 100 16)) ===> '(2 10 4)

But, we can also produce a list indicating where a zero occurs in another list:

```
(map_list zero? '(0 4 7 0)) ===> '(#t #f #f #t)
```

And we can produce a list of the squares of values of members of a given list:

```
(map_list (lambda (x) (* x x)) '(2 4 7)) ==> (4 16 49)
```

It is worth looking in detail at the evaluation of one of these
`map_list`
examples. This is written out below. If you are on-line, it is worth marking
each successive form of this expression and evaluating it - they all evaluate
to '(4 100).

```
(map_list
(lambda (x) (* x x))
'(2 10))
```

==> ; evaluate function and arguments, using the definition of map_list
```
(
(lambda (f l)
(if (null? l)
'()
(cons
(f (car l))
(map_list f (cdr l))
)
); end if
) ; end lambda
(lambda (x) (* x x))
'(2 10))
```

===> ; substitute arguments for parameters in body of
```
(if (null? '(2 10))
'()
(cons
((lambda (x) (* x x)) (car '(2 10)))
(map_list (lambda (x) (* x x)) (cdr '(2 10)))
)
); end if
```

===> ; evaluate the first argument of the special form if, choose accordingly
```
(cons
((lambda (x) (* x x)) (car '(2 10)))
(map_list (lambda (x) (* x x)) (cdr '(2 10)))
)
```

===> ; evaluate the function and arguments of the cons expression
```
(cons
((lambda (x) (* x x)) 2)
(map_list (lambda (x) (* x x)) '( 10))
)
```

===> ; which involves recursively evaluating ```
(cons
(* 2 2)
(
(lambda (f l)
(if (null? l)
'()
(cons
(f (car l))
(map_list f (cdr l))
)
); end if
) ; end lambda
(lambda (x) (* x x))
'(10))
)
```

===> again, substituting in the lambda-body
```
(cons 4
(if (null? '(10))
'()
(cons
((lambda (x) (* x x)) (car '(10)))
(map_list (lambda (x) (* x x)) (cdr '(10)))
)
); end if
)
```

===> and evaluating the if
```
(cons 4
(cons
((lambda (x) (* x x)) (car '(10)))
(map_list (lambda (x) (* x x)) (cdr '(10)))
)
)
```

===> evaluating the arguments of cons
```
(cons 4
(cons
((lambda (x) (* x x)) 10)
(map_list (lambda (x) (* x x)) '() ))
)
```

===> substituting in one lambda and using the definition of
```
(cons 4
(cons
(* 10 10)
(
(lambda (f l)
(if (null? l)
'()
(cons
(f (car l))
(map_list f (cdr l))
)
); end if
) ; end lambda
(lambda (x) (* x x))
'()))
)
```

===> substituting in body of lambda
```
(cons 4
(cons 100
(if (null? '())
'()
(cons
((lambda (x) (* x x)) (car '(10)))
(map_list (lambda (x) (* x x)) (cdr '(10)))
)
); end if
)
)
```

===> now we stop recursing because the condition is true
```
(cons 4
(cons 100
'()
)
)
```

===> and we are home and dry!
```
(cons 4 '(100))
```

===>
```
'(4 100)
```

Scheme provides strings as a datatype. For our purposes, a string can be regarded as a sequence of characters enclosed in double quotes, for example

"such bad news for the little tweetleoos - Big Bad Cat is on the loose"is a string. Do NOT confuse strings and atoms. Strings are used mostly for generating output text whose structure will be unanalysed. There is no case conversion with strings.

When a program changes the outside world, for example writing a message on the screen or a printer, it is hard to preserve a pure functional model. Scheme provides the following procedures:

(writeobj) (displayobj)

which will write an object on the `current-output-port`.
The difference between
the two is that `write`
is intended to produce output that can be read back into
Scheme, whereas `display`
is intended to produce output that can easily be read
back. In particular display does not print strings with quotes round them.

```
(display "hello")
```

outputs

hello (write "hello")

outputs

"hello"

UMASS Scheme also provides:

(writeln obj_{1}....obj_{n})

which outputs all its arguments starting on a new line (using display).

(writeln 2 3 4)

Procedures like write, which have an outside effect, are often combined using the begin special form.

(begin expr_{1}expr_{2}... expr_{n})

Evaluate the expressions in order. The value of the ` begin `
construct is the
value of the last expression, `expr _{n}`.

```
(define (test x)
(begin
(display "the value of x is ")
(display x)
(newline)
)
)
```

```
(test 45)
```

the value of x is 45

Actually, the ` begin `
statement is not necessary in the
` test `
function above, since Scheme allows one to have a sequence of
expressions as the body of a function, although the ` begin `
may
make the code clearer. You are encouraged to use `begin` in
such circumstances.

It may sometimes be useful to have a `begin`
expression in circumstances in
which you need to attain an outside effect and still have an expression which
has a definite value.

```
(define (monitor_and_add x y)
(+
(begin
(display "the value of x is ")
(display x)
(newline)
x
)
y
)
)
```

(monitor_and_add 2 3)
which produces the print out "the value of x is 2" and has the value 5. Here the begin expression acts as one of the arguments of +. Since its value is x, this will be added to y to obtain the result of the function.

Without the `begin`,
we are trying to add up the values of all the arguments of
+, which would cause an error.

```
(define (monitor_and_add x y)
(+
(display "the value of x is ")
(display x)
(newline)
x
y
)
)
```

If we evaluate:
```
(monitor_and_add 2 3)
```

we get:
Error: NUMBER(S) NEEDED Culprits: "Undefined Value", 5, In file: /users/users3/fac/pop/poplocal/local/Scheme/lecture4.scm

There are three functions in Scheme which can be used to test whether
objects are *equal*, namely `eq?`, `equal?` and
`=` . Of these `equal?` is the most generally useful. The =
function is intended to used for numbers. The use of `eq?` will be
explained later.

Scheme has a special form which allows you to introduce local variables into a function.

(letbindingsbody)

Here **body**
is a sequence of expressions and **bindings** has the form:

( (variable_{1}init) ...)_{1}

The meaning of the "` let `"
construct can be understood as
follows. All of the ** init ** expressions are evaluated, and the
corresponding **variable** bound to each of them. Each expression of
the **body** is then evaluated in sequence, using the new variable
bindings. The value of the `let` expression is the value of the
last expression in the body

A simple example of the use of `let` is:

```
(let ((a 2) (b 3) ) ( + a b))
```

which evaluates to `5`. While there is no benefit in the use of
`let` in this case (since `(+ 3 5)` is a simpler way to write
this, we can usefully use `let` when we have a sizable
common-subexpression in something we want to evaluate. For example, if we
are doing geometry in our computer we will often want to

```
(let ((d (sqrt (+ (* x x) (* y y)))))
(+ (/ x d) (/ y d)))
```

[We need to revise this explanation when we come to consider the imperative constructs in Scheme]

The variable bindings in the `let` construct are *local*,
that is to say the variables have the new values only inside the body of
the `let` statement. Thus the sequence:

```
(define x 55)
(begin
(writeln "before let x=" x)
(let ((x 2))
(writeln "in let, x=" x)
)
(writeln "after let, x=" x)
)
```

produces the output below (the first 55 arises from the `(define x
55)` expression, and the `"Undefined Value"` is the result of
the `begin` statement, that is in fact the result of the last
`writeln` expression.

55 before let x=55 in let, x=2 after let, x=55 "Undefined Value"

Note that *all* the expressions are evaluated before
*any* of the variables are bound. So,

```
(define x 55)
```

```
(let ((x 3) (y x)) (+ x y))
```

evaluates to 58, because the value of x that y is bound to is obtained before x is rebound to 3.

```
(let ((x 3) (y (+ 2 5))) (+ x y))
```

```
((lambda (x y) (+ x y)) 2 (+ 2 5))
```

There is also a special form `let` which is the same as let
except that each **init** expression is evaluated and the value bound to
the corresponding variable before the next `init`
expression is evaluated.
So

```
(let* ((x 3) (y x)) (+ x y))
```

evaluates to 6.

It is sometimes convenient to define recursive functions locally, especially
if they are acting as "helper" functions, so that there is no point in
cluttering up global name-space with unnecessary names. However we
* can't do this using * `let`. Consider:

```
(let ((sum1 (lambda (l)
(if (null? l) 0 (+ (car l) (sum1 (cdr l)))))))
(sum1 '(2 3 4)))
```

The problem is that the Scheme compiler will treat `sum`
occurring in the `lambda`
expression as a different variable from the one
introduced in the `let`
binding. The occurence of ` sum `
in the `lambda`
expression is * global *,
whereas that introduced by the `let`
binding is *local*.

This problem can be solved by using the `letrec` special form, which
allows you to define recursive functions locally. Syntactically this is the
same as `let` except that `letrec` replaces `let`. For
example:

```
(letrec ((sum (lambda (l)
(if (null? l) 0 (+ (car l) (sum (cdr l)))))))
(sum '(2 3 4)))
```

In the above example we ```
(letrec
((sum (lambda (l)
(if (null? l) 0
(+ (car l) (sum (cdr l)))))))
sum)
```

```
(define sum
(letrec
((sum (lambda (l)
(if (null? l) 0
(+ (car l) (sum (cdr l)))))))
sum))
```

Theorists would argue that the above is the