Allegheny College
Department of Computer Science
CS220 Programming Languages
Lab 7, March 12, 2007
CLISP
CLISP
To invoke the clisp command interpreter: $clisp
To compile a lisp source code file into an executable: $clisp -c lisp-file.lisp -o out-put-file
To view the clisp manual page: $man clisp
1. [1]> 102. [2]> -33. [3]> "hello"4. [4]> t5. [5]> nil6. [6]> ()7. [7]> (not t)8. [8]> (not nil)9. [9]> (and t t)10.[10]> (and nil t)
11.[11]> (or t nil)
12.[12]> (or () ())
13.[13]> (+ 10 -3)
14.[14]> (- 10 -3)
15.[15]> (+ 2 4 5 9 11)
16.[16]> (* 1.5 -6.5)
17.[17]> (/ 100 15)
18.[18]> (/ 100.0 15)
19.[19]> (! 4)
20.[20]> (! 50)
21.[21]> (> 5 6)
22.[21]> (> 6 5)
23.[22]> (<= 10 10)
24.[32]> (/ 45 3)
25.[23]> (= 15 45/3)
26.[24]> (- (+ 12 3) (* 4 9))
27.[25]> (/ (- 10 7) (sqrt 64))))))))))))))))))))
28.[25]> (/ (- 10 7) (sqrt 64))
29.[26]> (expt 2 4)
30.[27]> (expt 64 .5)
31.[28]> ; area of a circle with radius 5
32.[29]> (* pi 5 5)
33.[30]> ; convert 212 degrees Fahrenheit into Celsius
34.[31]> (* 5/9 (- 212 32))
35.[32]> ; convert 20 degrees Celsius into Fahrenheit
36.[33]> (+ (* 9/5 21) 32)
37.[34]> ; same, floating point
38.[35]> (+ (* 9/5 21) 32.0)))))))
39.[36]> ; define coefficients of the 2nd-degree polynomial 3x*x - 2*x - 1
40.[37]> (setf a 3)
41.[38]> (setf b -2)
42.[39]> (setf c -1)
43.[40]> a
44.[41]> b
45.[42]> c
46.[43]> (list a b c)
47a.[44]> (a b c)
47b.[44]> '(abc)
47c.[44]> 'a
48.[46]> ; quadratic formula (-b + sqrt(b*b - 4*a*c))/(2*a)
49.[47]> (/ (+ (- b) (sqrt (- (expt b 2) (* 4 a c)))) (* 2 a))
50.[48]> ; quadratic formula (-b - sqrt(b*b - 4*a*c))/(2*a)
51.[49]> (/ (- (- b) (sqrt (- (expt b 2) (* 4 a c)))) (* 2 a))
52.[50]> (defun quad1 (a b c)
53.[51]> "finds first solution to quadratic equation ax*x + b*x + c = 0"
54.[52]> (/ (+ (- b) (sqrt (- (expt b 2) (* 4 a c)))) (* 2 a))
55.[53]> )
56.[54]> (quad1 3 -2 -1)
57.[55]> (quad1 1 2 1)
58.[56]> (quad1 1 1 1)
59.[57]> (defun quad2 (a b c)
60.[58]> "finds second solution to quadratic equation ax*x + b*x + c = 0"
61.[59]> (/ (- (- b) (sqrt (- (expt b 2) (* 4 a c)))) (* 2 a))
62.[60]> )
63.[61]> (quad2 3 -2 -1)
64.[62]> (defun solve-quad (a b c)
65.[63]> "finds both solutions to ax*x + b*x + c = 0"
66.[64]> (list (quad1 a b c) (quad2 a b c))
67.[65]> )
68.[66]> (solve-quad 3 -2 -1)
69.[67]> (solve-quad 1 1 1)
70.[68]> (solve-quad 28.12 18.4 -12.4)
To save or record your interactions with the CLISP command interpreter, use the dribble command:
[1]> (dribble "name-of-output-file")
[2]> ....
[nn]>(dribble)
[nn+1]>(bye)
[1]> (defun ticket-price (age)
"Given the age of the purchaser, returns cost of a movie ticket:
$6.00 for adults, $4.50 for children under 12."
(if (>= age 12) 6 4.5)
)
[2]> (ticket-price 14)
6
[3]> (ticket-price 9)
4.5
(ticket-price 14)NESTED IF STATEMENTS
[1]> (defun temperature (degrees)
"classify temperature as below freezing, freezing, or above freezing"
(if (< degrees 32)
"below freezing"
(if (= degrees 32)
"freezing"
"above freezing"
)
)
)))))))
[2]> (temperature 45)
"above freezing"
[3]> (temperature 0)
"below freezing"
[4]> (temperature 32)
"freezing"
[2]> (setf friends '(dick jane sally))
(DICK JANE SALLY)
[3]> friends
(DICK JANE SALLY)
[4]> (setf enemies '(troll grinch ghost))
(TROLL GRINCH GHOST)
[5]> enemies
(TROLL GRINCH GHOST)
[10]> (setf enemies (remove 'ghost enemies)))
(TROLL GRINCH)
[11]> enemies
(TROLL GRINCH)
[12]> (setf friends (cons 'ghost friends))
(GHOST DICK JANE SALLY)
[13]> friends
(GHOST DICK JANE SALLY)
[14]> (defun newfriend (name)
(setf enemies (remove name enemies))
(setf friends (cons name friends)))
NEWFRIEND
[17]> (newfriend 'troll)
(TROLL GHOST DICK JANE SALLY)
[18]> friends
(TROLL GHOST DICK JANE SALLY)
[21]> enemies
(GRINCH)
[22]> (first '(lots of irritating parenthesis))
LOTS
[23]> (rest '(lots of irritating parenthesis))
(OF IRRITATING PARENTHESIS)
[24]> (first (rest (a b c)))
*** - EVAL: the function A is undefined
1. Break [25]>
[26]> (first (rest '(a b c)))
[27]> (first '(rest (a b c)))
REST
[28]> (cadr '(a b c))
B
[29]> (car (cdr '(a b c)))
B
[30]> (first (rest '(a b c)))
B
[31]> t
T
[32]> nil
NIL
[33]> (append '(a b) '(c))
(A B C)
[34]> (append '(a b C) '())
(A B C)
[35]> (list '(a b c) '())
((A B C) NIL)
[36]> (cons '(a b c) '())
((A B C))
[37]> (defun power (m n)
(if (zerop n)
1
(* m
(power m (- n 1)
))))
POWER
[38]> (power 2 2)
4
[39]> (power 2 1)
2
[40]> (power 2 0)
1
#1. Create a function that solves quadratic equations (see Using the CLISP Command Interpreter), and displays the answers in the following form:
[44]> (solve-quad 1 1 1)
("two complex solutions" #C(-1/2 0.8660254) #C(-1/2 -0.8660254))
[45]> (solve-quad 1 2 1)
("one real solution" -1)
[46]> (solve-quad 3 -2 -1)
("two real solutions" 1 -1/3)Solution:
[1]> (defun quad1 (a b sol)
(/ (+ (- b) (sqrt sol)) (* 2 a)))
QUAD1
[2]> (defun
quad2 (a b sol)
(/ (- (- b) (sqrt sol)) (* 2 a)))
QUAD2
[3]> (defun
solve-quad (a b c)
(setf sol (- (expt b 2) (* 4 a c)))
(if (< sol 0)
(list "two
complex solutions"
(quad1 a b sol) (quad2 a b sol))
(if (> sol 0)
(list "two real solutions" (quad1 a b sol) (quad2 a b sol)) (list "one real solution" (quad1 a b sol)))))
SOLVE-QUAD
[4]>
(solve-quad 1 2 1)
("one real
solution" -1)
[5]>
(solve-quad 1 1 1)
("two
complex solutions" #C(-1/2 0.8660254) #C(-1/2 -0.8660254))
[6]>
(solve-quad 5 -4 -2)
("two real
solutions" 1.1483314 -0.3483315)
#2 Create a function that creates a list
consisting of all the numbers from 1 through n, where n is any positive
integer.
Hint: The append function takes two or more lists and merges them into a single list. Compare the ouput of the following two statements:
[1]> (list 1 2 3) (1 2 3)
[2]> (append ‘(1) ‘(2) ‘(3)) (123)
Solution:
[3]>(defun number-list (n)
“create a list containing the integers from 1 through n”
(if (<= n 0)
nil ; empty list if n is 0 or less
(append (number-list (- n 1)) (list n))
)))))))
NUMBER-LIST
[4]>(number-list 3)
(1 2 3)
[5]>(number-list 0)
NIL
[6]>(number-list 10)
(1 2 3 4 5 6 7 8 9 10)
#3 Create a function named square-list that accepts a positive integer n. It should return a list of the frist n squares.
Sample Output:
[8]> (square-list 2)
(1 4)
[9]> (square-list 1)
(1)
[10]> (square-list 2)
(1 4)
[11]> (square-list 10)
(1 4 9 16 25 36 49 64 81 100)
[12]> (square-list -2)
NILSolution
(defun square-list (n)
"Returns a list of the first n squares"
(if (<= n 0) ;then
nil ;else
(append (square-list (- n 1)) (list (* n n)))
))
Nice list of online resources
Common Lisp
HyperSpec Online version of the Common Lisp standard
Pascal Costanza's
Highly Opinionated Guide to Lisp
Common Lisp Language
Overview
"Common Lisp: The
Language (2nd ed)" by Guy Steele
Object Oriented and Procedural Lisp
"Lisp as an alternative
to Java" (PDF file) From Intelligence, Volume 11, Issue 4
(December 2000), 21-24.
Complete text of
Touretzky's book on Common Lisp
The Common Lisp Cookbook
(lots of Lisp links at bottom)
Complete text of Graham's "On
Lisp"
Common Lisp pitfalls
(more advanced)
Remember that in general, functions evaluate their arguments, but there are some important exceptions to this. All exceptions are noted.
(+ x y), (- x y), (* x y), (/ x y)
--- Arithmetic functions of numbers. You can do things like (+ x y z w).
(random x)
--- If x is a positive integer, returns a random integer R satisfying
0 <= R < x. If x is a positive real number, returns a random real
number satisfying the same condition. (Note that (random 1) is always
equal to 0, while (random 1.0) is a real number between 0.0 and 1.0.)
(first lst), (second lst), ... (tenth lst)
--- Extract one of the elements of a list
(rest lst)
--- Returns the list obtained by removing the fist element in lst.
(car lst), (cdr lst)
--- Traditional names for (first lst) and (rest lst)
(cons expr lst)
--- Returns the list obtained by adding (the value of) expr onto
the front of lst. Note that (car (cons expr lst)) is the same
as expr, and (cdr (cons expr lst)) is the same as lst.
(list expr1 expr2 ...)
--- Returns the list whose elements are (the values of) expr1, expr2, ...
(append lst1 lst2 ...)
--- Returns the list obtained by stringing together the elements of
lst1, lst2, ... into a single list.
(quote foo)
--- Returns its parameter without evaluating it. So, for example, the
value of (quote a) is the symbol a and the value of (quote (a b c))
is the list (a b c). (quote foo) is almost always abbreviated using
the special notation 'foo. For example, 'a or '(a b c).
(= x y), (< x y), (> x y), (<= x y), (>= x y), (/= x y)
--- Boolean functions for testing numbers. ("/=" is "not equal")
(equal a b), (eq a b)
--- Tests whether a and b are equal. These have the same effect for
numbers, symbols, and strings. For lists, equal tests whether
the lists have the same members, while eq tests whether they
actually occupy the same memory location; it is like pointer equality.
Thus, (eq '(a b) '(a b)) is false, but after (setq lst '(a b)),
(eq lst lst) would be true.
(null x)
--- Tests whether x is NIL.
(atom x), (listp x), (stringp x), (numberp x), (symbolp x), (floatp x), (integerp x)
--- Test whether x is of the specified type.
(oddp x), (evenp x), (zerop x)
--- Test properties of numbers.
(not p), (and p q ...), (or p q ...)
--- The usual boolean functions. Note that and and or can take
multiple arguments. Also, AND and OR are often used as control
structures: AND evaluates its arguments until one comes out false, OR
evaluates its arguments until one comes out true (i.e. non-NIL); if OR
finds a non-NIL value, that value becomes the value of the OR.
(print x), (prin1 x), (terpri), (princ x)
---Output functions. (print x) outputs the value of x, followed by a
carriage return. (prin1 x) outputs the value of x without a carriage
return. (terpri) outputs a carriage return. Note that the value
returned by prin1 or print is the same as the value that was printed.
(princ x) is like (print x), except that, for example, quotes around
strings are NOT included in the output.
(read)
--- An input function. Lets the user type in a Lisp expression, and
returns that expression as its value.
(setq var expr)
--- Assigns the value of expr to var.
var is not evaluated and must be a symbol. Note that the value
that is returned by setq is the same as the value assigned to the variable.
(defun func (arg1 arg2 ...) expr1 expr2 ...)
--- Defines a function named func. arg1, arg2, ... are dummy parameters for
the function. func, arg1, arg2, ... are not evaluated and must be symbols.
When the function is called, expr1, expr2, ... are evaluated in order.
The value returned by the function is the value of the last expression,
unless a (return) causes the function to return early.
(return expr)
--- Breaks out of a loop, function, progn, etc. The value of expr
becomes the value of the loop or function. expr is optional; if it
is omitted, then the value is NIL.
(if test expr1 expr2)
--- Evaluates test. If it is true, expr1 is evaluated and its
value becomes the value of the if expression. In this case, expr2
is never evaluated. If test is false, then expr2 is evaluated,
its value becomes the value of the if expression, and expr1 is
never evaluated. expr2 is optional. If it is missing and if
test is false, then the value of the if is NIL.
(loop expr1 expr2 ...)
--- Repeatedly evaluates expr1, expr2, ... until a (return) or (return expr)
is executed. The value of the loop is the value returned by the (return).
(progn expr1 expr2 ...)
--- Executes expr1, expr2, once, in order. (This can be useful, for example
in an if, if you want to evaluate more than one one expression.)
(let ( (var1 val1) (var2 val2) ... ) expr1 expr2 ...)
--- var1, var2, ... become local variables that are assigned the
specified values as their initial values. var1, var2, ... must be
symbols, and they are not evaluated. expr1, expr2, ... are
then evaluated. The value of the let expression is the value of the
last expr.
(dolist (var lst) expr1 expr2 ...)
--- var (which is not evaluated and must be a symbol) takes on the
value of each element of the list lst in turn. For each of these
values, the expressions expr1, expr2, are evaluated. For example,
(dolist (x '(a b c)) (print x)) will print a, then b, then c.
(cond
(test1 expr expr ...)
(test2 expr expr ...)
.
.
.
(testn expr expr ...)
)
--- This is the traditional (if... else if... else if...) in Lisp.
test1 is evaluated. If it is true, the expressions following
test1 are executed. The cond terminates, and its value is
the value of the last expression that was executed. If test1 is
false, then test2 is checked in the same way. And so on. If
all the tests are false, then the value of the cond is NIL.
Note that the last test is often the atom T, whose value is true,
guaranteeing that the last set of expressions will be executed if none
of the previous ones are.Exercise I
Use the laboratory to work through the CLISP examples found in the above sections:
Use the "dribble" command to record your session with the interpreter as you work through the examples in Using the CLISP Command Interpreter.
Exercise II
Design and Implement CLISP solutions to the following problems using the CLISP Interpreter.
Deliverables
On Monday, March 26, 2007 hand-in copies of your recorded "dribble" session for Exercise I, as well as the solutions to the 5 problems in Exercise II.