Purpose: To review carefully old ground, and then pursue a little further some of the concepts which will allow you to write more interesting functions
3.1 Review  statement of lisp evaluation rules
By evaluate we mean different things for different lisp forms...
(hideousdisaster) "success") 
3.2 Review  anatomy of a function call
Please do not hold your breath for the entire duration of this section...
We are going to revise the story so far by looking at the simple lisp session below and examining each step in minute detail.
CLUSER 1 > (defun revlistof2 (mylist)We start by recalling the toplevel readevalprint loop, in which lisp repeatedly performs the following tasks:
(list (second mylist)
(first mylist)))
REVLISTOF2CLUSER 2 > (revlistof2 '(foo bar))
(BAR FOO)CLUSER 3 >
We recklessly decide to call our function with some test data. Looking at the function definition, we can see that it takes precisely one argument, named here mylist, and (given that we are handing that value on to functions like first) this argument has to be a list. The list we want to use for test data has two members: foo and bar. How do we construct this list? Several suggestions come to mind, but not all of them work:
The body of the function is the form (list (second mylist) (first
mylist)). We evaluate this by appealing yet again to the evaluation
rules above. list is a function, so we start by evaluating its
arguments. The first argument is the form (second mylist)  i.e.
a call to the function second. This call to second has
to (guess what!) evaluate its argument; the argument is the variable mylist
whose value is (foo bar) and so second is called with
argument (foo bar) and it duly returns the value bar.
Therefore the first of the two values which we are going to pass to the
function list is the symbol bar. Similarly the second
value passed to list is the symbol foo, and the call
to list returns the list
(bar foo)
which is finally printed out to the sound of massive celebrations by
all concerned.
(Did you remember to keep breathing?)
3.3 defun reconsidered
We recall that the syntax of defun is
(defun name (arg1 arg2
...) form1 form2 ... formn)
where name is the name of the function, arg1 etc.
are the names corresponding to the arguments to that function, and form1
etc. are the lisp forms to evaluate in order to process a call to that
function. The value returned by the final form formn is the value
to be returned by the call to the function itself.
Within the body of the function (i.e. during the evaluation of the forms form1 form2 etc) the names arg1 arg2 etc. are available to you as program variables. Their initial values are the results of evaluating the arguments to the function; in lisp parlance we say that these variables are bound to those values.
So if we have
(defun square (x)then during a call (square (+ 1 1)), the variable x is bound to the result of evaluating (+ 1 1).
(* x x))
The binding lasts only while the function is active. It ceases to exist on exit from the function and is not visible in calls to subfunctions (shallow binding); the following won't work...
(defun foo (wombat)(Question to check you're still awake: how would you get the variable wombat into the function bar?)
(bar))(defun bar ()
wombat)
3.4 More variables still
OK, so we know how to create variables on entry to functions and how to assign them values. Suppose we want to create further variables within the body of a function? We can do this by means of the special operator let*. For example, instead of
(defun addoneandsquareit (x)we could write
(* (+ x 1) (+ x 1)))
(defun addoneandsquareit (x)The syntax of let* is
(let* ((xplusone (+ x 1)))
(* xplusone xplusone)))
(let* ((var1 value1)
(var2
value2)
...)
form1
form2
...
formn)
Each of the pairs (vari valuei) represents a variable binding  the expression valuei is evaluated and the variable vari is bound to that value. The bindings are done in order:
3.5 Example  reading, writing and arithmetic
Let's trot out the example of converting temperatures from Fahrenheit to Celsius. Rather than writing a function which takes one value and returns another, i.e.
CLUSER 18 > (defun simplefahrenheittocelsius (fahrenheit)suppose that we have been asked to write a function which prompts the user for a value, reads it in and prints the result.
(float (* ( fahrenheit 32) 5/9)))
SIMPLEFAHRENHEITTOCELSIUSCLUSER 19 > (simplefahrenheittocelsius 212)
100.0CLUSER 20 > (simplefahrenheittocelsius 32)
0.0CLUSER 21 > ; very happy
CLUSER 31 > (fahrenheittocelsius)We need the following functions to handle reading and printing of lisp values:
Please give a value in degrees F: 32
32 degrees F is 0.0 degrees C.
NILCLUSER 32 > ; etc
read  reads a lisp form and returns it. At its simplest, a function of no arguments which reads from the listener. If no form has been typed yet, read will sit and wait until a complete form is available to it. 
format  function for generating formatted output. First
argument is a destination. Specify
=> "Hello, Nick." 
And the function definition looks like this:
(defun fahrenheittocelsius ()
(format t "~&Please give a value in degrees F: ")
(let* ((fahrenheit (read))
(celsius (float (* ( fahrenheit 32) 5/9))))
(format t "~&~a degrees F is ~a degrees C.~&" fahrenheit celsius)))
3.6 Further example  quadratic equations
If a quadratic equation is something you "know from nothing", don't panic. All we want to do is define a function of three numerical arguments a, b and c which returns a list of the following two values:
(assuming the squareroot is possible  if it isn't we'll generate an error instead).Don't ask why, just assume your lecturer has acquired a passion for daft formulae and let him get on with it.
Anyway, this example introduces three new functions:
<  predicate which takes any number of (numerical)
arguments and returns t if they are all in strictly ascending
order. Otherwise it returns nil. So
(< 499 499.8 500 1000) => t (< 1 2 3 4 6 5 7 8 9) => nil (< 0 0) => nil While we're here, > tests for descending order, and <= and >= are variants of < and > which allow arguments which are = (>= 2 1 1 1 0 0) => t 
sqrt  function of one number which returns its square root. 
error  function for flagging (signalling) errors. At its simplest, it is happy with a single argument (a string) which will be printed out as an error message. 
So here we go:
(defun quadraticsolve (a b c)or (imo better  why?)
(let* ((discriminant ( (* b b) (* 4 a c))))
(if (< discriminant 0)
(error "Discriminant was negative.")
(list (/ (+ b (sqrt discriminant))
(* 2 a))
(/ ( b (sqrt discriminant))
(* 2 a))))))
(defun quadraticsolve (a b c)
(let* ((discriminant ( (* b b) (* 4 a c))))
(if (< discriminant 0)
(error "Discriminant was negative.")
(let* ((squareroot (sqrt discriminant))
(denominator (* 2 a)))
(list (/ (+ b squareroot) denominator)
(/ ( b squareroot) denominator))))))
3.7 Further Logic
Some of the examples below will need the following pair of macros.
and  Takes any number of arguments. Evaluates them
in order until one returns nil, at which point and stops
evaluating things and returns
nil. If the last argument returns
nonnil, then and returns that value. Examples:

or  Takes any number of arguments. Evaluates them
in order until one returns a nonnil value, at which point or
stops evaluating things and returns that value. If the last argument returns
nil,
then or returns nil. Examples:

3.8 Practical Session
3.9 Suggested activity / exercises etc
Coming next: more about lists....