CMPS 350 Lab 02: Introduction to Functional Programming with Lisp

Geek Cultural References:

"Its all about you, using your own mind, without any method or schema, to restore order from chaos. And once you have, you can sit back and say, Hey, the rest of my life may be a disaster, but at least I have a solution." Marcel Danesi, author of The Puzzle Instinct: The Meaning of Puzzles in Human Life.

Lisp Eternal Flame

resources:
CLisp wiki (good introduction to syntax)
Gentle Introduction to COMMON Lisp (500 pp. PDF)
Lisp primer
Ch. 4 Finkel's Advanced Programming Language Design (36 pp. PDF file)
Functional programming (wiki)
Lisp (wiki)
Common Lisp reference
Practical Common Lisp by Peter Seibel
sample Lisp code
NOTE: You must kill your lisp process if you abort before exiting the lisp interpreter.

BACKGROUND MATERIAL

Complete this material before starting the lab. There is nothing to submit for this section! The purpose of this material is to prepare you for the coding problems that follow. Check your answers against these solutions.

Read chapter 2 of ANSI Common Lisp by Paul Graham (ch. 1 is optional). The full version of Graham's text can be purchased from Amazon.

Read this lisp primer for C and Java programmers.

Read this quick guide for a brief introduction on how to run a Lisp interpreter on sleipnir. There are two Lisp interpreters on sleipnir - Common Lisp (clisp) and Scheme (chicken). (The code from chapter 14 will run under chicken not common lisp.)

There are lots and lots of Lisp online references (see resource list above). You are welcome to use any or all, but we have installed the definitive online documentation to our implementation of CLisp here, and I recommend you use this as a definitive and complete reference.

Before starting to code do the following problems. Refer to this reference for help.

01. Use the Lisp interpreter on sleipnir to determine what happens when the 
    following expressions are evaluated.

   (a) > (* (+ 5 2) (- 7 5) )

   (b) > (list 1 (+ 2 3))

   (c) > (if (listp 1) (+ 1 2) (+ 3 4))

   (d) > (list (and (listp 3) t) (+ 1 2))

02. Replace the 'x' in the following statements with a Lisp operator or
    variable that will produce the outcome as shown.

   (a) > (car (x (cdr '(a (b c) d))))
         b 


   (b) > (x 13 (/ 1 0))
         13

   (c) > ((lambda (y) (* y 2)) x) 
         6 

    (d) >  (let ((y 3)) (* y x))
        6

03. Use car and cdr to return the fourth element of a list.

04. Find three distinct cons expressions that return (a b c). Since Lisp is 
    case insensitive, (A B C) is identical. However, the list ((A B C)) is 
    not equivalent to (A B C). One list has one element and the other list 
    has three.

05. Given this Lisp function definition

   (defun test (n)
     (if (<= n 1)
        1
     (+ n (test (- n 1)))))

    Explain how (test 3) will be evaluated.

06. Explain how this function will be evaluated. 

    (list (or t (listp 3)) (+ 1 2))

For the next questions, write and run the following two Lisp functions. The easiest way is to copy and paste or write the function in a file, load the file and run the functions; e.g.:
     > (load 'lab02.lisp)
     > (enigma '(a b)) 
     > (mystery 'a '(a b c)) 
This README file provides more detailed instructions.
 
07. What does this function return?

      (defun enigma (x)
         (and (not (null x))
           (or (null (car x))
             (enigma (cdr x)))))

08. What does this function return?

    (defun mystery (x y)
       (if (null y)
           nil
           (if (eql (car y) x)
              0
              (let ((z (mystery x (cdr y))))
                 (and z (+ z 1))))))

   Note: 'let' establishes variable bindings. This is not the same as an 
   assignment statement. For example: (let ((z 5)) (+ z 1))  binds z to 5, 
   increments z, and returns 6. 

LAB 02 INSTRUCTIONS

Code the following functions in a single lisp file named lab02.cl.
01. Write an iterative function that takes a positive integer and prints 
    that many dots.

02. Write a recursive function that takes a positive integer and prints 
    that many dots.

03. Write a recursive function that takes a list and returns the number of 
    times the symbol 'a' occurs in it. Note: do not count a's that might
    occur in a sublist within the list.

04. Write a recursive function that returns the Fibonacci number where the
    Fibonacci sequence is defined as

    fib(0) = 0, fib(1) = 1 and fib(n) = fib(n-1) + fib(n-2) for n > 1.
    examples:
    n =       0 1  2  3  4  5  6   7   8  9   ...
    fib(n) =  0 1  1  2  3  5  8  13  21  34  ...

05. Write a function that takes 2 numbers and returns the greater of the two.

06. Write a recursive function that takes an integer n and returns the 
    summation of n and all positive integers preceding it; e.g., passing 5 
    will return 15, which is 1+2+3+4+5.

07. Define a function test that runs all six of the above functions. Call this 
    function in lab02.cl. You can use the code below. The output of calling test 
    should look like this:
 
    CMPS 350 Lab02   Name: Santa Claus 
    01. 5 iterative dots: .....
    02. 5 recursive dots: .....
    03. a's in (b c (a) a): 1
    04. fib 7 = 13
    05. greater 5 or 7? 7
    06. 1+2+3+4+5 = 15

; you can use this test function - just change function names to your own
 
(defun test()
    (format t "CMPS 350 Lab02 Name: santa claus%")
    (format t "01. " ) (dot1 5) (format t "~%")
    (format t "02. 5 recursive dots: ") (dot2 5)    (format t "~%")
    (format t "03. a's in (b c (a) a): ~D~%" (amount '(b c (a) a)))
    (format t "04. fib 7 = ~D~%" (fib 7))
    (format t "05. greater 5 or 7? ~D~%" (big 5 7))
    (format t "06. 1+2+3+4+5 = ~D~%" (sum 5) )
)
;; don't forget to call test!!!!
(test) 

HOW YOUR LAB WILL BE GRADED

My script will assume your lisp code resides in the following location:
      /home/stu/{username}/cs350/lab02/lab02.cl 
You will be marked off -1 pt if your code is not protected! To protect your code change permissions on cs350 only:
    $chmod 700 cs350  
Do not change permissions on your home directory or I cannot get your files. You do not need to change permissions on any files below cs350.