basic lisp programming common lisp follows the algorithm below when interacting with users: loop...
TRANSCRIPT
Basic LISP Programming
Common LISP follows the algorithm below when interacting with users: loop read in an expression from the console; evaluate the expression; print the result of evaluation end loop.
Sample Session
(* 2 (cos 0) (+ 4 6)) 20.0
(defun double (x) (* x 2)) DOUBLE
(double 3)6
This is a program typed into a text file
;; Triple the value of a number;;
(defun triple (X) "Compute three times X." ; Inline comments can (* 3 X)) ; be placed here.
;;;; Negate the sign of a number;;
(defun negate (X) "Negate the value of X." ; This is a comment (- X))
Name the file testing.lisp.
Now load the definition into the LISP environment by typing:
> (load "testing.lisp")T
Recursions and ConditionalsWe can implement a function to compute factorials using recursion:
(defun factorial (N) ;; Compute the factorial of N. (if (= N 1) 1 (* N (factorial (- N 1)))))
Note: LISP treats NIL as false, and everything else as true.
Relational Operators
The Trace Function (trace factorial)
(FACTORIAL)USER(12): (factorial 4) 0: (FACTORIAL 4) 1: (FACTORIAL 3) 2: (FACTORIAL 2) 3: (FACTORIAL 1) 3: returned 1 2: returned 2 1: returned 6 0: returned 24
24
Recall the definition of Fibonacci numbers: Fib(n) = 1 for n = 0 or n = 1 Fib(n) = Fib(n-1) + Fib(n-2) for n > 1
LISP code: (defun fibonacci (N);; Compute the N'th Fibonacci number (if (or (zerop N) (= N 1)) 1 (+ (fibonacci (- N 1)) (fibonacci (- N 2)))))
Built-in Shorthands and Predicates
The or form logical operator
It evaluates its arguments from left to right, returning non-NIL immediately if it encounters an argument that evaluates to non-NIL. It evaluates to NIL if all tests fail.
Logical Operators
Lists
(cons 1 (cons 2 nil)) (1 2)
(quote (2 3 5 7 11 13 17 19)) (2 3 5 7 11 13 17 19)
'(2 3 5 7 11 13 17 19) (2 3 5 7 11 13 17 19)
Your session may look more like this:
USER(24): (first '(2 4 8))2USER(25): (rest '(2 4 8))(4 8)USER(26): (first (rest '(2 4 8)))4USER(27): (rest (rest '(2 4 8)))(8)USER(28): (rest (rest (rest '(8))))NIL
Recognizers
Corresponding to each constructor of a data type is a recognizer. In the case of list, they are null for nil and consp for cons. Given a list L, (null L) returns t iff L is nil and(consp L) returns t iff L is constructed from cons.
USER(29): (null nil)TUSER(30): (null '(1 2 3))NILUSER(31): (consp nil)NILUSER(32): (consp '(1 2 3))T
recursive functions that traverse a list.
• The LISP built-in function list-length counts the number of elements in a list.
USER(33): (list-length '(2 3 5 7 11 13 17 19)) 8
we could implement our own version of list-length as follows:
(defun recursive-list-length (L) (if (null L) 0 (1+ (recursive-list-length (rest L)))))
SymbolsUSER(45): 'a ; LISP is case-insensitive.AUSER(46): 'A ; 'a and 'A evaluate to the same symbol.AUSER(47): 'apple2 ; Both alphanumeric characters ...APPLE2USER(48): 'an-apple ; ... and symbolic characters are allowed.AN-APPLEUSER(49): t ; Our familiar t is also a symbol.TUSER(50): 't ; In addition, quoting is redundant for t.TUSER(51): nil ; Our familiar nil is also a symbol.NILUSER(52): 'nil ; Again, it is self-evaluating.NIL
With symbols, we can build more interesting lists:
USER(53): '(how are you today ?) ; A list of symbols.(HOW ARE YOU TODAY ?)
USER(54): '(1 + 2 * x) ; A list of symbols and numbers.(1 + 2 * X)
USER(55): '(pair (2 3)) ; A list containing 'pair and '(2 3).(pair (2 3))
Notice that the list (pair (2 3)) has length 2:
Example: nth
LISP defines a function (nth N L) that returns the N'th member of list L (assuming that the elements are numbered from zero onwards): USER(59): (nth 0 '(a b c d)) A USER(60): (nth 2 '(a b c d)) C