Select this to skip to main content [CSUSB] >> [CNS] >> [Comp Sci Dept] >> [R J Botting] >> [CSci620] >> lab15 [Source]
[Index] [Schedule] [Syllabi] [Text] [Labs] [Projects] [Resources] [Search] [Grading]
Notes: [01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15] [16]
Tue May 18 12:17:04 PDT 2004


    CS620 LISP Laboratory Number 2

      Check out New things on the Course Web Page

      [ ]


      This lab should teach you how to create and use new arithmetic functions. We will tackle LISP data structures in the next lab.


      To earn full credit the work must be done before the end of the lab and should contain a list of at least 3 notes. Each note is a short paragraph with one or two sentences and a new LISP function (or link to a file containing the function). The sentences should say what the function does and what you learned by writing it.

      Let me know by calling me across to your workstation when done.


      1. To run LISP open a terminal window. No source to edit..... in this lab!
      2. To leave XLISP send EOT by holding down CTRL and tapping D
      3. Parentheses (...) are the must important things in LISP.
      4. A comment in XLISP starts with a ";" and runs to the end of the line.
      5. Keep your handout on LISP open beside you and look in it for the rules of LISP. The XLISP manual is on the web at [ lisp.txt ] as a plain ASCII text file.
      6. Open many windows and use your hilight-and-paste feature to save time.
      7. Use an editor to write your functions and their test cases then either
      8. Any text editor is good for LISP, but vi can help you track the parentheses.
      9. Put XLISP code in files that end ".lsp".
        1. In 'vi' you can track parentheses if you do the following
           		:set showmatch
          • Copy and paste into a window running XLisp to run them...
          • or
          • Save the version ( :w in vi) and run xlisp on it. (:!xlisp % in vi)

      10. Some browsers may panic if you link to a ".lsp" file. If you put source code in a ".txt" file every browser in the world will read it and your user's will love you.

      (End of Net)


      Start by rereading your last set of notes.

      Here are some simple LISP expressions/commands. Load the LISP interpreter and input each in turn. Try to predict what each will return as a value before inputting it:

       		(+ 1 2)
       		(1 + 2)
       		(* (+ 1 2) (+ 3 4))
       		(+ 1 2 3 4)
       		(A B C)
       		'(A B C)

      Displaying the structure of a LISP value

      LISP data is stored in what is called a binary tree: each item of data is a "leaf"(an atom), empty (NIL) or a pair (car . cdr). We call the car and cdr of a pair the branches:
       		((1   .   2) . 3)
      The data looks like this (with a 'o' replacing the '.').
       		   / \
       		  o   3
       		 / \
       		1   2

      1. tree::= NIL | leaf | pair,
      2. pair::= (car . cdr),
      3. leaf::=atom,
      4. car::=tree,
      5. cdr::=tree.

      (End of Net)

      Down load/Save this file as text: [ show.lsp ]

      Use this UNIX command to look inside the file:

       			cat show.lsp

      Run this UNIX command in a terminal window:

       			xlisp show.lsp

      Inside the running XLISP try these command:

       			(show '(a b))
       			(show '(a b c))
       			(show '(a b c d))
       			(show '((a b)(c d)))

      This function (or something like it) is a handy tool when you want to see the structure of a complex list structure.... for example the value show itself.

      			(show show)

      Creating new functions

      Here is a function with no arguments:
       		( defun a () 4321)
       		(a 1)
       		(+ a 1)
       		(+ (a) 1)
      Copy and paste the above XLISP commands into XLISP in a terminal window.

      Then define and test a new function called answer that returns the value 42.

      Functions with a single parameter

      Here is how we would define a LISP function with a single argument that returns a list:
       		(defun square (x)           (* x x))
      Here is how you test it...
       		(square 3)
       		(square 4)
       		(square 5)

      Here is how you can use it:

       		(square (+ 1 2 3))
       		(+ (square  3) (square 4) )
       		(+ 3 (square 3) )
      Test the above!

      Here is how XLISP can list it:

      XLISP does not let you edit a function however!

      Do not leave LISP until you complete the next two steps.

      Here is a function for the cube:

       		(defun cube (x)           (* x (square x)))
      Test it.

      Define a function called fourth that returns the fourth power of a number. Use the fact that the fourth power on n is the square of the square of n:

    1. n^4 = (n^2)^2.

      Test it. And save it...

      Functions with two or more parameters

      Functions of more arguments/parameters are done the same way using the syntax
    2. ( defun name (w x y z ...) expression)

      Here is a definition of a function with two arguments in LISP:

       		(defun pythagoras (x y) (+ (square x) (square y)))
       		(pythagoras 3 4)
      Some common errors
       		(pythagoras 4)
       		(pythagoras 1 3 4)
       		(pythagoras )

      Here is a function that return the larger of two expressions:

       		(defun max2 (a b) (cond ((> a b) a) (T b)))
       		(max2 1 17)
       		(max2 17 1)
       		(max2 (max2 3 5) (max2 4 1))
       		(max2 (square 3) (cube 2))

      Define a function called min2 that returns the smallest of two arguments. Test it and save it....

      From the book -- Association lists

      XLISP has
       			(assoc expression a-list)
      as a built in function. Example
       		(assoc 2 '((1 a) (2 b) (3 c)))
      Finds the value of the expression in the a-list and returns the pair.
       		(2 b)
      Test it out... it is not the one in the book.

      Define a new function called bookassoc that does work like the one in the book and uses assoc to do the hard work.

      A Binary Search

      Here is a function that searches for the positive square root of a positive number. It uses the square function. It has four arguments:
      1. target: the number for which you need a root. Must be >=0.
      2. lo: a number that is less than the root.
      3. hi: a number that is greater than the root.
      4. error: a number indicating the desired accuracy of the approximation.

       (defun binroot (target lo hi error )
       	(let (( mid (/ (+ lo hi) 2.0))) ; this saves the time to recalculate mid
       	 (if (<= (- hi lo) error)
       	     (if (< (square mid) target)
       	         (binroot target mid hi  error)
       	         (binroot target lo  mid error)
      Here is how I tested it:
       		(binroot 50 0 100 0.05)
      Test it further and trace it.

      The above algorithm will find roots of any monotonic increasing function. Modify it to find cube roots and fourth roots of positive numbers.

      From the book -- Property lists

      In XLISP we have:
      • (get symbol property) ; book's get
      • (putprop symbol value property) ; almost book's put
      • (remprop symbol property) ; remove a property
      • (symbol-plist symbol) ;get the property list of a symbol
      Test these out.

      We don't have the book's put function. Use one of the above functions to define the book's put function.

      Optional experiments if you have time

        Higher powers

        The following function works out the value of x to the power n when n is a whole number greater than or equal to 0.
         		(defun power (x n)
         			((= n 0) 1)
         			((= n 1) x)
         			(T (* x (power x (- n 1))))
        Here are two test cases
         		(power 2 3)
         		(power 3 2)
        Test with the trace function....

        However this is not a very fast way to calculate powers. There is another one based on these facts:

        1. If n is even then n=2*k for some k and so power(x,n)=square(power(x,k)).
        2. If n is odd then n=2*k+1 for some k and so power(x,n)=x*square(power(x,k)).

        (End of Net)
        We have LISP function EVENP and ODDP to detect parity and (/ n 2) works out a k for us by rounding down.

        Can you figure out how to speed up the original power function?

        An example of top-down design in LISP

        [ primes.html ]

      . . . . . . . . . ( end of section Optional experiments if you have time) <<Contents | Index>>

      Leave LISP

      To exit lisp, input the EOT character CTRL/D

    . . . . . . . . . ( end of section CS620 LISP Laboratory Number 2) <<Contents | Index>>


  1. BNF::="Backus-Naur Form", for syntax and grammar, developed by Backus and Naur.
  2. EBNF::="Extended " BNF.
  3. HTML::= "HyperText Markup Language", used on the WWW.
  4. HTML_page::syntax= "<HTML>" head body.
  5. Java::="An " OO " Language from Sun".
  6. LISP::= "LISt Processing Language".
  7. LRM::="Language Reference Manual".
  8. OO::="Object-Oriented".
  9. Prolog::="Programming in Logic".
  10. TBA::="To Be Announced".
  11. UML::="Unified Modeling Language".
  12. URL::=Universal_Resource_Locator,
  13. Universal_Resource_Locator::syntax= protocol ":" location, where
    1. protocol::= "http" | "ftp" | "mailto" | ... ,
    2. location::= O( "//" host) O(pathname).

    (End of Net)
  14. WWW::= See, index to web site for this class.
  15. XBNF::="eXtreme" BNF, developed by the teacher from EBNF, designed to ASCII input of syntax, semantics, and other formal specifications.

Formulae and Definitions in Alphabetical Order