CS 3723
 Programming Languages 
   Lisp Functions  


Embedded hyphen, underscore, or dot in identifiers: Note below that lisp allows a hyphen, underscore, or dot inside identifiers, whether variables or function names:

hyphen, dot, or underscore inside lisp identifiers
hyphen underscore dot
(defun length-1 (list-1)
   (cond
      ((null list-1) 0)
      (t (+ 1 (length-1
           (cdr list-1)))) ))

> (length-1 '(a b c)) 3
(defun length_1 (list_1)
   (cond
      ((null list_1) 0)
      (t (+ 1 (length_1
           (cdr list_1)))) ))

> (length_1 '(a b c)) 3
(defun length.1 (list.1)
   (cond
      ((null list.1) 0)
      (t (+ 1 (length.1
            (cdr list.1)))) ))

> (length-1 '(a b c)) 3


Example Lisp Functions: Note that all but one of the functions below use the identifier list for the name of the formal parameter of the function. The identifier list is also the name of an important list processing function in lisp. This function is not used below, but it is commonly needed and used in functions like these. It might be better to use a different identifier name, but there will be no problem (except for possible confusion) if the same name is used as a parameter and as a built-in function.

length Output
% cat length1.l
(defun length1 (list)
   (cond
      ((null list) 0)
      (t (+ 1 (length1 (cdr list)))) ))
> (length1 ())
0
> (length1 nil)
0
> (length1 '(a b c))
3
> (length1 '((a b) c (d e (f))))
3

word lookup Output
% cat myfind.l
(defun myfind (word sent)
   (cond
      ((null sent) 'not-found)
      ((equal word (car sent)) 'found)
      (t (myfind word (cdr sent))) ))
> (myfind 'is '(now is the time))
FOUND
> (myfind 'for '(now is the time))
NOT-FOUND
> (myfind '(a) '(a b c))
NOT-FOUND
> (myfind '(b) '(a (b) c))
FOUND
> (myfind '(c (d e)) '((a b) (c (d e)) e (f)))
FOUND

add Output
% cat add.l
(defun add (list)
   (cond
      ((null list) 0)
      (t (+ (car list) (add (cdr list)))) ))
> (add '(2))
2
> (add '(2 3))
5
> (add '(2 3 4))
9
> (add nil)
0
> (add 3)
>>Error: The value of X, 3,
   should be a LIST
> (add '(2 (3 4)))
>>Error: The value of NUMBER1, (3 4),
   should be a NUMBER

add-all (numbers at all levels)
% cat add-all.l
(defun add-all (list)
     (cond ((null list) 0)
           ((atom (car list)) (+ (car list) (add-all (cdr list))))
           (t (+ (add-all (car list)) (add-all (cdr list))))   ))
> (add-all '(1))
1
> (add-all '(2 3))
5
> (add-all '(3 4 5))
12
> (add-all '(2 (3 4)))
9
> (add-all '( ( (2 3) 4) ( 1 5)))
15


Three Versions of list-atoms function: Here we want to list all atoms from an S-expression, from all levels inside.

list-atoms: first try
% cat list-atoms.l
(defun list-atoms (list)
   (cond
      ((null list) nil)
      ((atom (car list)) (cons (car list) (list-atoms (cdr list))))
      (t (append (list-atoms (car list)) (list-atoms (cdr list)))) ))
> (list-atoms ())
NIL
> (list-atoms '(a))
(A)
> (list-atoms '(a b))
(A B)
> (list-atoms '(a (b c)))
(A B C)
> (list-atoms '((a b) c (d (e (g) f))))
(A B C D E G F)
> (list-atoms '(() a))
(NIL A)                                *** NOT CORRECT ANSWER ***
> (list-atoms (car '(()a)))
NIL
> (list-atoms (cdr '(() a)))
(A)
> (append nil '(a))
(A)
> (atom (car '(() a)))
T
> (atom ())
T                                  *** OK, HERE'S THE PROBLEM ***
> (cons (car '(() a)) (list-atoms (cdr '(() a))))
(NIL A)

list-atoms: second try
% cat list-atoms.l
(defun list-atoms (list)
   (cond
      ((null list) nil)
      ((null (car list)) (list-atoms (cdr list)))
      ((atom (car list)) (cons (car list) (list-atoms (cdr list))))
      (t (append (list-atoms (car list)) (list-atoms (cdr list)))) ))

> (list-atoms ())
NIL
> (list-atoms '(a))
(A)
> (list-atoms '(a (b c)))
(A B C)
> (list-atoms '((a b) c (d (e (g) f))))
(A B C D E G F)
> (list-atoms '(() a b))
(A B)
> (list-atoms '(() a))
(A)
> (list-atoms '(nil (a nil ()) () b nil ()))
(A B)

list-atoms: third try
% cat list-atoms.l
(defun list-atoms (list)
   (cond
      ((null list) nil)
      ((and (not (null (car list))) (atom (car list)))
           (cons (car list) (list-atoms (cdr list))))
      (t (append (list-atoms (car list)) (list-atoms (cdr list)))) ))


> ; note: how append and cons handle nil 
  (append nil '(a) nil)
(A)
> (cons 'a nil)
(A)
> (list-atoms '((a b) c (d (e (g) f))))
(A B C D E G F)
> (list-atoms '(nil (a nil ()) () b nil ()))
(A B)


Example: Define a function count-atoms that will count the number of atoms in a list, at all levels. For example (count-atoms '(a (b c) (d (e) f))) should return 6. [Hint: Mimic list-atoms from class.]
Example: Write a ``super'' reverse function srev which reverses all lists that occur in an S-expression at any level. Thus (srev '((a b (c d)) e (f g))) should yield ((g f) e ((d c) b a)). [Hint: This is similar to the previous reverse1, except for additional recursion.]


Revision date: 2013-11-03. (Please use ISO 8601, the International Standard Date and Time Notation.)