LISP



<ATOM>  -->  <non-blank>+
<LIST>  -->  (  <S-EXP>*  )
<S-EXPR>-->  <LIST>  |  <ATOM>

special items (atoms)

numbers T NIL = ()

to run LISP (interactive) [on Abacus or SOD cluster]

clisp

to leave LISP

(bye)
or
^D			[control-D]


basic operations

'A			you enter
 A			your response

'(A B C)
 (A B C)

T NIL ()  37
T NIL NIL 37

A
ERROR

37 ;comment
37

expressions

( +  5  3 )		=  8
( -  5  3 )		= 2
( * 5  3 )		=  15
( / 15  3 )		=  5
( + ( * 3 5 ) ( / 8 2 ) )  = ?

list operations

car cdr

(car  '(a  b  c))	=  a
(car  '((a b)(d e)))	= (a b)
(cdr  '((a b)(d e)))	= ((d e))

cons

(cons  'a  '(  b  c))	= (a b c)
(cons nil  '(  b  c))	= (nil b c)
		      or= (() b c)

append

(append '(a b) '(c d))	= (a b c d)

setq

(setq  a  '(b c))	= (b c)
a			= (b c)

(setq a '(a b c d))	= (a b c d)
(car a)			= a
(cdr a)			= (b c d)
(setq b a)		= (a b c d)
(cons (car a) (cdr a))
(cons   '( a   b ) '( c   d ) )         ==  ( ( a  b )  c  d )
         ---------   ^
	   |         |
	   +---------

(append '( a  b ) '( c  d ) )           ==  ( a  b  c  d )

logic functions

T - true
NIL-false
	(actually all non nil values are considered true)

input			value returned
(atom 'a)		t
(atom '( x y )) 	nil
(atom 5)		t
(atom t)		t
(atom nil)		t          <-----  special
(setq a '( a b c ))
(atom a)		nil
(null 'a)		nil
(null  a)		nil
(null  nil)		t

(> 5  3 )		t
(= 3  3 )		t

IF style testing

really case or switch statement

(cond
      ( ( > 5 3 )    3)
      ( ( = 5 3 )    2)
      ( t            1)
)

(setq a  '( 1 2 ))

(cond
   ( ( > (car a)  1)	(car a))
   ( ( = (car a)  1)    (cdr a))
   ( t                  'error)
)

LISP functions



(defun try (a) a)

(try 'abc)		==	abc
(try 5)			==	5

(defun my-car (arg) (car arg)) (my-car '(x y z)) == x

Debugging

(trace   fname)
(untrace fname)
after an error use
:h
To bring in a file into lisp
(load "file-name")
Note: you will want to use the % character in vi to check for balanced parenthesis.
(defun smaller ( x y )
  (cond
    (( < x y )    x)
    ( t           y)
  )
)


(smaller 1 2 )		== 	1
(smaller 2 1 )		==	1

LISP Recursion

(defun smallest ( alist )
 (cond
   ((null alist)     alist)
   ((atom alist)     alist)
   ((null (cdr alist)) (car alist))
   ( t                (smaller(car alist) (smallest (cdr alist))))
 )
)

(smallest  '( 5 1 3 2 ))	==	1

(trace smallest)
(smallest '(5  1  3  2))
enter1		((5  1  3  2))
enter2		((1  3  2))
enter3		((3  2))
enter4		((2))
leave4		2
leave3		2
leave2		1
leave1		1

(untrace smallest)
(trace smaller)
(smallest '(5  1  3  2))
enter		(3  2)
leave		2
enter		(1  2)
leave		1
enter		(5  1)
leave		1

Recursion and Looping in LISP

(defun list-items (s)
 (cond
   ((null s)  s)
   ((atom s)  s)
   (t (print (car s))(terpri)(list-items(cdr s)))
 )
)
(defun list-items2 (s)
 (do    (( b  s))		; declare b with starting
				; value of s

	((null  b)  s)		; stop when b is nill
				; return s

	(print (car b))		; these three lines are the body of the loop
	(terpri)
	(setq b (cdr b))
 )
)
(defun list-items3 (s)
 (do    ((b s (cdr b)))		; declare b with starting value of s
				; step b by (cdr b)
        ((null b)  s)
	(print (car b))
	(terpri)
 )
)


If you want to list all atoms in an s-expression, with possible lists within lists you need a dual recursive routine. This routine will list all non nill atoms.

(defun list-atoms (s)
  (cond 
    ((null s) s)
    ((atom s) (print s))
    (t (list-atoms (car s)) (list-atoms (cdr s)))
  )
)

If you want to do this correctly, you need also to list the nill's in the lists. This is left as an exercise for the reader. Note, be sure you do not list extra nill's.

By the way, the following will list the atoms, but it will also show a large number of nils, some of which you want, some not.

(defun list-atoms (s)
  (cond
    ((atom s) (print s))
    ((null s) s)
    (t (list-atoms (car s)) (list-atoms (cdr s)))
  )
)