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.
Hints
Net
:set showmatch
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)
A
'A
(A)If you get one wrong... you may need to go back to [ 11.html ] again.
You know that LISP has double quoted strings:
"I am a string!"You already know that a single quotation mark stops the interpreter from evaluating a list.
'(+ 1 2)
(setq day 'wednsday)
'(Today is day)A backquoted list starts with a backquote (`) and is treated as a constant list that contains some expressions. All you do is put a comma(,) in front of the expressions.
`(Today is ,day)(day is replaced by the value of the variable day)
Or
`((+ 1 2) = ,(+ 1 2))
Or
`( example1 ( (sqrt 4.0) = ,(sqrt 4.0) ) ( day = ,day))
Note. This is a feature that I only learned about in 2005... it
looks like it may be useful in the future.
Creating new functions
Here is a function with no arguments:
( define (a) 4321)
(a)
a
'a
(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:
(DEFINE (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:
squareXLISP 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:
(DEFINE (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:
Test it. And save it...
Functions with two parameters
Functions of more arguments/parameters are done the same way
using the syntax
Here is a definition of a function with two arguments in LISP:
(DEFINE (pythagoras x y) (+ (square x) (square y)))
(pythagoras 3 4)Some common errors
(pythagoras 4)
(pythagoras 1 3 4)
(pythagoras )In our XLISP the value of the function name is an expression defining a function:
pythagoras
Here is a function that return the larger of two expressions:
(define (max2 a b) (if (> a b) a 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....
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:
(define (binroot target lo hi error )
(let (( mid (/ (+ lo hi) 2.0))) ; this saves the time to recalculate mid
(if (<= (- hi lo) error)
mid
(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.
Optional experiments if you have time
(define (power x n)
(cond
((= n 0) 1)
((= n 1) n)
(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:
Net
Can you figure out how to speed up the original power function?
Classic factorial
We now define a new function, command and kind of expression
that calculates the factorial of a positive integer. The factorial
of the number 0 is 1, and for all other positive integers n you
work out n times the factorial of n-1. In LISP we say:
(define (factorial n)
(if (= n 0) 1 (* n ( factorial ( - n 1 ) ))
)
)
Here you print out the definition of factorial:
factorialHere you input expressions that apply factorial to simple numbers:
(factorial 0)
(factorial 3)
(factorial 5)
Trace how it works:
(trace factorial)
(factorial 0)
(factorial 3)
(factorial 5)
(untrace factorial)
Below you can use factorial is more complicated ways:
(factorial (factorial 3))
(setq n 3)
(factorial n)
(setq f (factorial n))
f
(setq f (factorial f))
f
The problem with this factorial is that n! quite a small n is too large to be represented as an integer. Worse n! when n<0 is infinitely small! As a result we should define a safe factorial that returns a string "error" when n<0 or n is too big.
Program and test this one.
An example of top-down design in LISP
[ primes.html ]
. . . . . . . . . ( end of section Optional experiments if you have time) <<Contents | End>>
Leave LISP
To exit lisp, input the EOT character CTRL/D
. . . . . . . . . ( end of section CS320 Lab 12 LISP Laboratory Number 2) <<Contents | End>>
Check the Preparation for next class
[ ../13.html ]