Lab #1: Lisp Introductory Lab

Part 1: Basic Lisp Primitives

1. Start up CLISP by typing clisp at the prompt.

2. Write sequences of FIRSTs and RESTs that will pick the symbol PEAR out of the following expressions:

(apple orange pear grapefruit)
(((apple) (orange) (pear) (grapefruit)))
(apple (orange) ((pear)) (((grapefruit))))

3. Execute the following statements. What do the functions cons, append, and list do?

; This is a comment, by the way!
(cons 'x '(1 2))
(cons '(1 5) '(2 3))
(append '(1) '(2 3))
(append '(1 5) '(2 3))
(list '1 '2 '3 '(4 5))

4. Execute the following code. What resulted, and why?

(setf mylist '(hey there dude))
(first mylist)
(setf (first mylist) 'bye)
mylist

5. Execute the following code. What do length and reverse do?

(length '(plato socrates aristotle))
(reverse '(plato socrates aristotle))

6. Enter the following code.

(nth 1 mylist)

What does nth do?

Part 2: Editing code and defining functions

Clearly, you don't want to keep entering all your code into the CLISP prompt. You can write functions in a text editor, then load them into CLISP. You can use any editor you want, but I strongly recommend learning emacs. It's the right tool for the right job, especially when programming in LISP.

1. From the terminal window, type

emacs part2.lisp &

This will open up an emacs window to edit the program part2.lisp.

2. Type in some Lisp code:

(setf x (+ 3 2))

3. Save your program by keying ctrl-x followed by ctrl-s, or going to the menu bar and selecting Files, followed by Save Buffer.

4. In your CLISP window, type

(load "part2.lisp")

This will execute whatever code is in your file. In CLISP, type

x

at the prompt. You should see a 5 in response.

5. Remove the code that you currently have in part2.lisp, and instead type or copy in the following. Hit the tab key on each line so that emacs will automatically indent your code for you. Save when done.

(defun both-ends (whole-list)
   (cons (first whole-list)
         (last whole-list)))

6. In CLISP, load in the function. Then type

(both-ends '(breakfast lunch dinner snack pizza))

What does the function both-ends do? How? Where is the name of the function? Where are the parameters of the function? How does it determine which value to return?

7. Define ROTATE-LEFT, a function that takes a list as its argument and returns a new list in which the former first element becomes the last.

8. You can declare "local" variables in LISP via the use of the let function. For example, run the following code:

(let ((a 1) (b 2))
  (setf a 7)
  (setf c (+ a b))
)

After executing this code, what are the values of a, b, and c? Why?

Part 3: Conditionals

Lisp has four different predicates for testing equality. For now, the only two you need to worry about are equal and =.

1. At the CLISP prompt, type

(setf x '(hi there))
(setf y '(hi there))
(setf z 'bye)
(equal x y)
(equal x z)

What kind of responses do you get? Why?

2. At the CLISP prompt, type

(equal 4 4.0)
(= 4 4.0)
(= x y)

What kind of responses do you get?

In short: = only works on numbers, but will return the correct answer if the types are different. equal will work on all types, but distinguishes between numbers of different types as different.

3. Define the function DIVISIBLE-BY which takes two numeric arguments, and determines if the first is divisible by the section. For example, (divisible-by 10 2) should return T, while (divisible-by 10 3) should return NIL. Use the built in function REM that takes two integer arguments and returns the remainder when the first argument is divided by the second.

4. Enter the following code:

(setf x 5)
(if (= x 3)
    (setf y 9)
(setf y 10))

What value is assigned to y? What's happening here? (Hint: if-then-else)

The following code acheives the same purpose, and is much cleaner. Why does it work?

(setf x 5)
(setf y (if (= x 3) 9 10))

5. Enter the following code:

(setf x 8)
(setf y (cond ((= x 3) (+ 3 8))
              ((= x 8) 12)
              (t (* 6 3))))

Can you change the value of x to get different values of y? What does the cond function do?

Part 4: Recursion

1. Enter and load the following function. What does it do? Why?

(defun mystery (m n)
  (if (zerop n)
      1
    (* m (mystery m (- n 1)))))

Note that there is no "return" statement here, as you would find in a similar function in C++. Why? How is the return value determined in the above function?

2. Write a function, keep-first-n, that returns a list of the first n elements in a list. You may assume that there are at least n elements.

Example:

> (keep-first-n 3 '(a b c d e f g h i))
(A B C)

Part 5: Iteration and printing

1. Enter and load the following function. What does it do? Why?

(setf count 0)
(loop
 (if (equal count 10) (return count) nil)
 (format t "~%Count = ~a." count)
 (setf count (+ count 1)))

Try removing the ~% from the format statement. What does the ~% do? What does the ~a do?

What purpose does (return count) serve?

2. Enter the following code:

(setf x 8)
(if (equal x 8) (progn (setf y 2)
                       (setf z 3))
  (progn (setf y 7)
         (setf z 9)))

What purpose does progn serve? Where does the return value come from?

Further exercises, due on Wednesday, 1/10/01.

Use the program hsp to turn in these programs. You should submit one file called hw1.lisp which contains the definitions for the four functions assigned below. Use usual good programming style: indent code appropriately, document your code where hard to read, and include header comments for each function indicating author, purpose of the function, etc. If you need more information on hsp, check out http://www.mathcs.carleton.edu/system_notes/hsp.html .

1. Create functions num-times-A-iterative and num-times-A-recursive, which are iterative and recursive definitions of a function that takes a list and returns the number of times the symbol A occurs in it.

2. Create functions add-position iterative and add-position-recursive, which are iterative and recursive definitions of a function which takes a list and returns a list of each element plus its position. For example:

> (add-position-iterative '(7 5 1 4))
(7 6 3 7)