Purpose: Loose ends / CLOS in 10 minutes / revision quiz / summary
12.1 Loose ends
There are a couple of specific points that I want to tie up. The first
is that one of the great things about lisp is that it offers so many different
ways of expressing your intent. Recall from the first lecture:
language is a language in which you describe the problem you are working
on and the computer decides how to solve it. Lisp and Prolog are declarative
I am still unhappy with the thought of languages being declarative
(if that is what the word means) - although code like
On the other hand a procedural
language is a language in which you tell the computer what to do. The
machine will then do what you tell it and you hope that what it tells you
is the answer to the question you wanted to ask. Pascal is a procedural
(def-url "/" ...) ; define root
page of my web server
is getting close to that ideal. However, I think it is indisputable that
lisp gives you so many ways of telling the computer what to do that you
can effectively get on with the task of describing your actual problem
relatively unencumbered by small details.
For example, the following would all find the position in the list things
of a sublist of length 1. The first is fairly compact, and fine if you
know how to use the :key argument to position. The next
is almost as neat but depends on knowing about position-if, the
third works but might be criticized for wasteful allocation (generating
a list of length (length things) and then throwing it away again).
The dolist form uses "primitive" parts, which is fine and might
even in some circumstances run faster than the others; the mapc-closure
solution is quite frankly revolting. Presumably, we could also have written
a recursive function to do the search.
(position 1 things :key 'length)
A lot of the functions I have told you about take additional (optional)
arguments, and I may not always have told you about these. They quite frequently
permit greater flexibility, and sometimes additional sophistication, in
how you use them. For example, the following
(position-if #'(lambda (x) (= (length x) 1)) things)
(position 1 (mapcar 'length things))
(let ((where 0))
(dolist (x things)
(when (= (length x) 1)
(let ((where 0))
(mapc #'(lambda (x)
(when (and x (not (cdr x)))
(return-from found where))
(or (gethash key table)
both allow you to retrieve a value from a hash-table and state a default
value in case the key wasn't present. However, suppose that the
present in the table, and the value stored against it is
In the first case above, gethash returns nil and so the
form returns default; in the second, gethash again finds
and returns nil. So the second form, while ostensibly similar
to the first, can be used to distinguish between a stored value of nil
and no stored value.
(gethash key table default)
You'll find many cases like this in lisp: where different treatments
can have similar results but for fine tuning you have to really know how
each operator works.
12.2 What did we miss out? (incorporating "CLOS in
We have covered around 160 Common
Lisp symbols - looked at one way that's one sixth of the language.
In practice, it's considerably more than that because a lot of the remaining
symbols involve more book-work to cover less ground. (Or: less dramatic
ground.) I'd reckon we're about half-way there. We didn't touch:
packages (other than in passing)
streams (other than in passing)
pathnames (other than very much in passing)
defining your own setf behaviour
multiple values (other than in passing)
the complex loop macro
the condition system
advanced macro building techniques
extending the syntax
vast numbers of functions dealing with lists, arrays, string, characters,
So why use Lisp? Because it is
It offers (see also the
Y2K proof ;-)
It is particularly suitable for applications which are
simple consistent syntax
a rich set of datatypes
run-time (dynamic) typing
automatic memory management (garbage collection)
a fully integrated object system (CLOS)
sophisticated error handling
stunningly powerful macro system ("programs as data")
features (such as unwind-protect and closures) which you simply
won't find elsewhere
12.4 Revision Quiz
large and complex
12.5 Practical session / Suggested activity
How would you add (i.e. insert) an extra element to the start of a list?
How could you splice two lists together?
How would you add (i.e. insert) an extra element to the end of a list?
Suppose you wanted to perform some operation on each element of a list:
how could you do this? (3 different answers...)
What kinds of things can you use lists for?
Give an example of a special operator.
How could you find out the variable value of a symbol?
How could you find out whether a symbol had a functional value?
Give an example of a lisp object which is of two types, neither of which
is a subtype of the other.
True or false: every valid expression, when evaluated, returns a value?
True or false: and is a function?
How could you define a function so that it can take 0 or more parameters?
How do you give a default value for an optional argument?
Give five lisp datatypes.
What does eval do?
What defining forms do you know?
Give some advantages of macros.
Give an example of an iterative operator.
Give 3 different equality predicates.
How would you decide which equality predicate to use?
If you wanted to find an operator which worked on strings, you might look
in a reference manual in the chapter on string operators. Which other chapters
would you look in?
What is tail recursion?
How do you write comments in lisp code?
What conventions do you know for lisp code?
How would you choose whether to use structures, hash-tables, lists or arrays
for a particular application?
What kinds of applications do you think lisp is good for?
How do you ask a lisp programmer if they want a drink?
12.6 Revision reading
Implement a recursive function to find the position in a given list of
a sublist of length 1.
Implement the function append. Is your solution elegant? fast?
Implement a function which takes a lisp object and says something useful
about it (the way that describe does).
Go back through all the practicals and exercises and complete everything
you missed out first time through.
As a final word, I just want to thank all my students at APU for helping
me deliver this course, for working so hard and (I hope) for coming to
appreciate at least the edges of why for me lisp is the only language
to write your programs in.
Graham chapters 1-8 and 10
Take at least one look through chapter 13 and appendix D of Graham.
Last modified 2000-09-14
$Id: //info.ravenbrook.com/user/ndl/lisp/declarative/lectures/lectures/lecture-12.html#2 $