Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
10, 2002
This introdu
tion isn't intended to give you all the details, but just enough to get a
ross
the essential ideas, and to let you get under way qui
kly. The best way to make use of
it is in front of a
omputer, trying out all the things mentioned.
1
languages (e.g., for planning or for NLP) and write interpreters for these languages
in Lisp.
List stru
tures are a very
exible data type { it's hard to think of any types of
information that
an't be easily represented as list stru
tures. And as long as we're
using list stru
tures as our data types, we
an enter data just by supplying list
stru
tures { we need not write spe
ial reading or stru
ture-building fun
tions. For
instan
e,
(SETQ X '(THREE (BLIND MICE) SEE (HOW (THEY RUN)) !))
sets the variable X to the indi
ated list stru
ture value; and
(READ)
will read in any list stru
tre. Similarly printing out list stru
tures requires no
spe
ial printing fun
tions (the fun
tions PRINT and FORMAT do almost everything
we need). Common Lisp arrays and re
ord stru
tures are also pretty easy to handle
in I/O.
The simpli
ity and elegan
e of Lisp, and its unmat
hed
exibility and ease of use
for AI appli
ations, have made it very durable: it is the se
ond-oldest high-level
programming language (after FORTRAN), yet is still in
ommon use.
Getting started
Go to the dire
tory where you want to work (and where you'll typi
ally have various
program les and data les), and type
lisp
The system will respond with loading and initialization messages, followed by a prompt
like
CL-USER(1):
You
an now type in expressions and have them evaluated. Whenever you've got balan
ed
bra
kets and hit enter, the value (or an error message) is printed, and then you're
prompted for further input.
Getting out
To es
ape from Common Lisp, type
(exit), or :exit
Saying \Hello"
A
ording to N. Wirth (author of ALGOLW and Pas
al), a good way to get an initial
glimpse of a language is to see a program that prints \hello". Here's the Lisp version
(just one quoted symbol!):
'hello
When you hit enter, you'll get
2
HELLO
whi
h is the result of evaluating 'hello. If you want lower
ase, you
an use the
hara
ter
string
"hello"
whi
h yields "hello" (still in quotes) { i.e., strings evaluate to themselves. If you want
the quotes to be invisible, you
an use
(format t "hello")
However, besides getting \hello" without quotes you'll now also get NIL on a new line;
that's be
ause the format fun
tion is spe
ial, having both an ee
t and a value: the ee
t
is to print out the material in quotes (plus possibly values of variables { see example
below), and the value is NIL.
But suppose we want a more elaborate greeting, wherein the user is asked for her/his
name. Then we
ould dene a hello-fun
tion as follows:
(defun hello ()
(format t "Hello, what's your first name?~%")
(setq *name* (read))
(format t "Ni
e to meet you, ~a" *name*) )
Note that the rst argument of defun is a fun
tion name, the se
ond is a list of arguments
(here, none), and after that we have any number of expressions whi
h will be evaluated
in sequen
e, and whi
h
omprise the \body" of the denition. In ee
t, defun just
makes a -expression out of the argument list and the body, and makes this lambda
expression the fun
tion-value of the rst argument (the fun
tion name). In other words,
it provides a way of naming a -expression. (Note that the fun
tion value of a symbol
won't interfere with other ordinary values we might asso
iate with it; but generally it's
wise to steer away from su
h multiple uses of a symbol.)
The ~% in the rst format statement means \go to new line". The setq expression
sets the global value of *name* to be whatever Lisp expression is read in by (read).
A symbol
an have both a global value, and a value lo
al to a parti
ular fun
tion
all.
But it's
onventional to use an initial and nal \*" for global variables, and to avoid
using these as lo
al variables. (We'll see lo
al variables in later examples.) The ~a in
the se
ond format statement means \print the value of the next expression given as
additional argument of format" { and in this
ase the next argument is *name*, and its
value is whatever name the user supplied.
When we type in this fun
tion denition and hit enter, we get
HELLO
whi
h is just the name of the fun
tion we've dened. (So even an expression that denes
a fun
tion gets a value.) However, defun is primarily evaluated for its ee
t, not its
value, and the ee
t as indi
ated is that Lisp will now \remember" the denition of the
hello fun
tion.
To exe
ute the hello fun
tion, we type
(hello)
3
and hit enter, with the result
Hello, what's your first name?
Joe (assumed as user input)
Ni
e to meet you, JOE
NIL
The nal NIL is the value returned by the hello fun
tion when it terminates. Of
ourse,
we
an also use the expression (hello) as part of another program, whi
h does not
immediately terminate after the greeting.
In general, we
an evaluate fun
tions for parti
ular arguments by writing
(fun
tion-name arg1 arg2 ... argn )
Sin
e hello had no arguments, we wrote (hello). Ex
ept for
ertain fun
tions like
defun, setq, and a few others, arguments are rst evaluated, and only then is the
fun
tion applied to the argument values.
5
(setq A (make-array '(3 4) :initial-
ontents
'((a b
d) 2 3 4)
("this" 5 6 7)
(#\C 8 9 10)) ))
(defstru
t
ourse
name time
redits room instru
tor)
(setq CSC242 (make-
ourse :name "Artifi
ial Intelligen
e"
:time 'TR3\:00-4\:15
:
redits 4
:room 'CSB601
:instru
tor "John M
Carthy"))
(setf (
ourse-instru
tor CSC242) "Marvin Minsky") ;
hanges instru
tor
(
ourse-time CSC242) ; yields |TR3:00-4:15|
6
Dotted pairs and binary trees
It's usually most
onvenient to think of our data (and programs) as atoms and lists.
However, list stru
tures are a
tually built out of dotted pairs. You
an think of these as
pairs of storage lo
ations (
ells) where ea
h lo
ation
ontains a pointer either to an atom
or to another dotted pair. In this way we
an build up arbitrary binary trees, and these
an be used to represent list stru
tures. (But while all list stru
tures
an be represented
as binary trees, not all binary trees represent list stru
tures; so dotted pairs in prin
iple
provide slightly more
exibility than list stru
tures.) Here are examples of how we build
list stru
tures out of dotted pairs:
(A) is really (A . NIL), or internally, Here denotes a
pointer to NIL
A
A B C
A B
C D E
An example showing that not all binary trees are lists is the following tree:
The left part of a dotted pair (i.e., the destination of the left pointer) is
alled its CAR,
and the right part its CDR (pronoun
ed \
ould'r"). CAR also has the alternative name
first, sin
e it pi
ks out the rst element of a list, as seen in the following.
7
(
dr '(A B)) is the same as (
dr '(A . (B . NIL)) whi
h yields
(B . NIL),
i.e., (B)
Similarly (
ar '(A B C)) yields A "first of list"
(
dr '(A B C)) yields (B C) "rest of list"
There are also fun
tions se
ond, third, ..., tenth for easy a
ess to the rst few ele-
ments of a list, though we
ould also use (
ar (
dr ...)), (
ar (
dr (
dr ...))),
et
. Additional \easy a
ess" fun
tions you should know about are
aar,
adr,
dar,
ddr,
aaar, ...
ddddr as well as nth, nth
dr, and last (whi
h does not give
the last element of a list, but rather the last dotted pair, i.e., a list
ontaining just the
last element). Here are some more examples, assuming that we have dened x by the
indi
ated setq:
(
ar x) ==> A
(
dr x) ==> (B (C D E))
(
ar (
dr x)) = (
adr x) ==> B
(
dr (
dr x)) = (
ddr x) ==> ((C D E))
(
ar (
dr (
dr x))) = (
addr x) ==> (C D E)
(
dr (
dr (
dr x))) = (
dddr x) ==> NIL
(first (third x)) = (
aaddr x) ==> C
(se
ond (third x)) ==> D
(last (third x)) ==> (E)
B C
(CONS ’(A B) ’(C (D E))) yields ((A B) C (D E))
etc.
8
Basi
me
hanism: expression evaluation
Note that expressions like
yielding
~~~~~~~~
'hello HELLO
(load "my-file") NIL
(setq n 5) 5
(
ar '(a b
)) A
(
ons 3 n) (3 . 5)
9
list-stru
ture { a fun
tion that
he
ks whether its argument is a true list stru
ture
(i.e., it's not an atom other than NIL and prints without \dots"). Again we use
tail-re
ursion.
standard-dev { a fun
tion for
omputing the standard deviation (root mean square
deviation from the mean) of a list of numbers. This illustrates the use of the \fell
swoop" fun
tions redu
e and map
ar, as well as dire
t use of a lambda-expression.
10