`defun`

defining form.
Defining a function with `defun`

looks like this:
`(defun`

*fn-name* `(`

*arg-1* ... *arg-m*`)`

*exp-1* ...
*exp-n*`)`

where *fn-name* is an identifier as are
*arg-1* to *arg-m*. The body of the function is the
sequence of expressions *exp-1* to *exp-n*. A function is
called as was described earlier in function
application, by using the identifier which names the function in the
operator position of the application, for example:

`(fn-name`

*exp-1* ...
*exp-m*`)`

calls the function defined with the name `fn-name`

, passing as
arguments the *values* of the expressions *exp-1* to
*exp-m*. Note that there are the same number of expressions in the
call to the function as there are defined arguments in the definition.

`(defun`

*fn-name* `(`

*arg-1* ... *arg-m* `rest:`

*arg-m+1*`)`

*exp-1* ...
*exp-n*`)`

This defines a function which accepts *at least* *m*
arguments. There are three cases to consider:

**fewer than***m*arguments:- This is an error, and the system should tell you so, just as when the wrong number of arguments is supplied to a fixed arity function.
**exactly***m*arguments:-
*arg-1*to*arg-m*receive the corresponding values of the argument expressions and*arg-m+1*receives the value`()`. **more than***m*arguments:-
*arg-1*to*arg-m*receive the corresponding values of the argument expressions.*arg-m+1*receives a list whose elements are the values of the remaining argument expressions.

`foo1`

takes 0 or more arguments and returns the
list of those arguments. `foo2`

takes 1 or more arguments and
returns the list constructed by joining the first argument on to the front of the
list of the second and subsequent arguments. `foo3`

takes 1 or
more arguments and returns the list of the second and subsequent arguments.
`size`

. We will define
a function called `list-length`

.First, we must work out the algorithm. This also illustrates a common way of solving problems in Lisp and in the many functional languages descended from it and lambda-calculus (its theoretical underpinning), where we identify one case for which the result is trivial and the general case which is successively reduced to the trivial case. If you have done mathematical induction, you will find this obvious: this is just induction over a structure.

**trivial case:**- is of an empty list, that is
`()`. The length of`()`is 0. **general case:**- is of a non-empty list. Given
a list, we can obtain a list that is one element shorter by taking its
`cdr`

. Thus, the length of the non-empty list is 1 plus the length of its tail.

`null`

. Its result is `t`

. Also note that the
input again extends over more than one line.
To confirm our understanding of how `list-length`

works, let
us consider its application to the list `'(a b c)`

:

`append`

function. As before, we tackle the development
of the algorithm by identifying a trivial case and a general case:
**trivial case:**- the empty list, the reverse of which is the empty list.
**general case:**- if we can reverse the tail of
the list and then tack the head on to the end, we have reversed a
non-empty list. The second bit uses
`append`

.

`append`

joins `l`

into a list, using the constructor function
`list`

.
We can use the same analysis technique as before to see how
`reverse-list`

works:

Julian Padget, jap@maths.bath.ac.uk, this version December 9, 1994