Assignment title: Information
ITECH5403 ATMC Dr. Haidar AL-Khalidi
1
LISP
There are many compilers for lisp, the most popular one is
Clisp, and also you can use lispWorks (LW)
Clisp: http://sourceforge.net/projects/clisp/files/latest/download
lispWorks: http://www.lispworks.com/products/ide.html
======================================
Lisp tutorials
http://opensourceforu.efytimes.com/tag/lisp-tears-of-joy-series/
S-expressions
(+ 1 2) : means 1+2
(+ 1 2 3 4 5) 1+2+3+4+5
(/ (* 4 5) (+ 2 3)) ((4*5)/(2+3))
Evaluation
Lisp evaluates everything. It even evaluates its arguments. In Lisp, numbers evaluate to
themselves — that is, any time Lisp tries to evaluate 1, the answer is always 1.
> 1
1
> 2
2
In Lisp, + is a function, and an expression like (+ 1 2) is a function call. When Lisp evaluates a
function call, it does so in two steps:
1. First, the arguments are evaluated, from left to right. In the case of (+ 1 2), each argument
evaluates to itself, so the values of the arguments are 1 and 2, respectively.
2. The values of the arguments are passed to the function named by the operator. In this case,
it is the + function, which returns 5.
If any of the arguments are themselves function calls, they are evaluated according to the same
rules. So when (/ (* 4 5) (+ 2 3)) is evaluated, this is what happens:ITECH5403 ATMC Dr. Haidar AL-Khalidi
2
1. Lisp evaluates (* 4 5): 4 evaluates to 4 and 5 evaluates to 5. These values are passed to
the function *, which returns 20.
2. Lisp evaluates (+ 2 3): 2 evaluates to 2 and 3 evaluates to 3. These values are passed to
the function +, which returns 5.
3. The values 20 and 5 are sent to the function /, which returns 4.
By the way, if you make a mistake and CLISP starts acting crazy, just type :q and it'll fix
everything. When you want to shut down CLISP, just type (quit).
Loop in Lisp
(loop
for i from 1 to 10
do (print i))
Quote
Lisp evaluates everything. Sometimes you don't want Lisp to do that; in situations like
these,quote is used to override Lisp's normal evaluation rules. This quote is a special operator.
It has a distinct evaluation rule of its own, which is to evaluate nothing. It takes a single
argument, and returns it verbatim.
> (quote (+ 7 2))
(+ 7 2)
> (quote(the list (+ 2 3 5) sums 3 elements))
(THE LIST (+ 2 3 5) SUMS 3 ELEMENTS)
quote = '
> (list '(+ 0 1 1 2 3 5) (+ 0 1 1 2 3 5))
((+ 0 1 1 2 3 5) 12)
setq
Most programming languages provide a special notation for assignment. Lisp does no such
thing. Instead, Lisp uses its routine workhorse, the function. Lisp has a special function, called
setq, that assigns the value of one of its arguments to the other argument. To accomplish the
equivalent of x <-- 47 in Lisp, we write the following:
> (setq x 47)
47
> (setq y (+ 4 7))
11ITECH5403 ATMC Dr. Haidar AL-Khalidi
3
> (+ 3 (setq z (* 3 7)))
24
>z
21
> (setq my-medium-of-expression "Lisp")
"Lisp"
Comment line in lisp
Use single, double, triple and quadruple semicolon (; ;; ;;; ;;;;)
Single-semicolon comments are all aligned to the same column at the right; usually
each comment concerns only the code it is next to. Occasionally a comment is long
enough to occupy two or three lines; in this case, it is conventional to indent the
continued lines of the comment one space (after the semicolon).
Double-semicolon comments are aligned to the level of indentation of the code. A
space conventionally follows the two semicolons. Such comments usually describe
the state of the program at that point or the code section that follows the comment.
Triple-semicolon comments are aligned to the left margin. They usually document
whole programs or large code blocks.
Quadruple-semicolon comments usually indicate titles of whole programs or large
code blocks.
Use #| |# to comment out larger amounts of Lisp code.
Defining local functions in LISP
To define a local function, use the flet command. This, too, has two parts: (1) function
declaration; and (2) the flet body, where the function may be called. The function declaration
itself consists of a function name, the arguments to that function, and the function body, where
we put the function's code. As with let, we can define one or more functions within the scope of
the flet. But remember that these are local functions visible only in the body — they may not
call one another, and so cannot be recursive. Here's an example:
> (flet ( (foo(n)
(+ n 5))
)
(foo 2))
7
> (flet ( (foo(n)
(+ n 5))ITECH5403 ATMC Dr. Haidar AL-Khalidi
4
(bar(n)
(+ n 10)))
(bar (foo 2)))
17
Here, I have declared two functions: foo and bar. In this code example, the body of the flet first
calls foo with 2 as its argument, to return a value of 7; it then calls bar to add 10 to this value,
leading to 17 as the final value of the whole flet expression. See Figure 2.
Figure 2: 'flet' expression
Let's see what happens when bar tries to call foo in its function body:
> (flet ( (foo(n)
(+ n 5))
(bar(n)
(+ (foo 2) n)))
(bar 10))
*** - EVAL: undefined function FOO
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of (FDEFINITION 'FOO).
RETRY :R2 Retry
STORE-VALUE :R3 Input a new value for (FDEFINITION 'FOO).
ABORT :R4 Abort main loop
>
That's right! You get slapped in the face with an error (Figure 3). The flet command creates
local functions, which are invisible inside another function body.ITECH5403 ATMC Dr. Haidar AL-Khalidi
5
Figure 3: Error
To define recursive local functions, use labels. Local functions defined by a labels expression
can refer to any other functions defined there, including themselves. This is identical in its basic
structure to the flet command. Here's the preceding code, written with labels:
> (labels ( (foo(n)
(+ n 5))
(bar(n)
(+ (foo 2) n)))
(bar 10))
17
In this code example, the body of the labels expression calls the local function bar.
Since labelsallows local functions to see each other, the bar function calls another local
function (from inside its body). That is foo, which adds 2 to 5, resulting in a value of 7, which in
turn is added to 10 — the argument of the bar function, resulting in a final value of 17.
Function
(defun power (x y)
(if (> y 0)
(* x
(power x (- y 1)))
1))
To call a function put its name and its arguments between to round brackets (power 5 2)ITECH5403 ATMC Dr. Haidar AL-Khalidi
6
Another example:
(defun min1()
(setq x 5)
(setq y 10)
(if (> x y)
(print y))
(if (< x y)
(print x))
)
if statement
(if (> 5 4) ;; if-part
(print "5 is greater than 4") ;; then-part
)
Then statement execute on sentence only. If we want to execute more than
one sentence we should use (progn).
progn : it is used to create block in LISP
ex: here if value equals 2, then print (you have chosen two then you have chosen two two
twice)
(if (= value 2)
(progn
(print "you have chosen two")
(print "you have chosen two two twice")))
While this will only print "you have chosen two" and then skip the other print)
(if (= value 2)
(print "you have chosen two")
(print "you have chosen two two twice"))ITECH5403 ATMC Dr. Haidar AL-Khalidi
7
if – else statement
(if (> 4 5) ;; if-part
(print "4 falsely greater than 5!") ;; then-part
(print "4 is not greater than 5!") ;; else - part
)
Print
(print 2)
2
(setq x 20)
(print x)
20
(setq s 33
( if (= s 33)
(print s)))
format t : it is used to print on the listener.
(format t "you have chosen three~%")
~% : new line
read: used to read a value from the consol.
(setq choice (read))
The value you going to enter it will be saved inside choice.
(read) can read the input only till the space. (read in lisp is equal to next() and next.Int()
in java)
read-line: used to read a value from the consol.
(setq name (read-line))
(read-line) reads input including space between the words. (read-line in Lisp is equal to
next.Line() in java)ITECH5403 ATMC Dr. Haidar AL-Khalidi
8
Recursive or iterative?
Unlike some other functional programming languages, Lisp provides for both recursive and
iterative programming styles. As an example, consider writing a function to compute the factorial
of a positive integer n. The factorial, written n!, is the product of all integers between 1 and n;
i.e., n! = n×(n-1)×(n-2)×…×2×1. A function to compute this number can be written in a recursive
style as follows:
(defun fac(n)
(if (= n 0) 1
(* n (fac (- n 1)))))
You should read the definition of the function as follows. If n is zero, then return 1; otherwise
return the product of n and the factorial of n-1. The same function can be written in an iterative
style as follows:
(defun fac(n)
(let ((result 1))
(dotimes (i n)
(setq result (* result (+ i 1))))
result))
This function uses let to set up a local variable called result with an initial value of 1. It then
performs n iterations of a central loop that each time multiplies the result by the loop's counter
variable (one must be added to this counter, as dotimes counts from zero). Finally, the value of
the result variable is returned as the result of the function.
Object-oriented
Like many other modern programming languages, Common Lisp is object-oriented. In fact, it was
the first ANSI-standard object-oriented language, incorporating CLOS (the Common Lisp Object
System). CLOS provides a set of functions that enable the definition of classes, their inheritance
hierarchies and their associated methods.
A class defines slots whose values carry information about object instances. The class definition
can also specify default values for slots, and additional non-trivial behavioural mechanisms (such
as integrity checking) performed at object creation time. As an example of object-orientation in
Lisp, consider the definition of some shapes, which can be either circles or rectangles. A shape's
position is given by x and y coordinates. Further, a circle has a radius, whereas a rectangle has a
width and a height. It should be possible to compute the area of circles and rectangles. A working
set of definitions is given below:
(defclass shape ()
(x y))
(defclass rectangle (shape)ITECH5403 ATMC Dr. Haidar AL-Khalidi
9
((width :initarg :width)
(height :initarg :height)))
(defclass circle (shape)
((radius :initarg :radius)))
(defmethod area ((obj circle))
(let ((r (slot-value obj 'radius)))
(* pi r r)))
(defmethod area ((obj rectangle))
(* (slot-value obj 'width)
(slot-value obj 'height)))
Using these definitions, a rectangle (instance) can be created with make-instance, for example,
with a width of 3 and a height of 4:
> (setq my-rect (make-instance 'rectangle :width 3 :height 4))
#
Its area can be computed by calling the method area:
> (area my-rect)
12
;; main menu
Ex1:
(defun menu ()
(format t "1: Eating Here~%")
(format t "2: Takeaway~%")
(format t "3: Exit~%")
(format t "-----------~%")
(format t "please select one:~%")
(setq value (read))
(if (= value 1)
(format t "You have chosen one Eating Here"))
(if (= value 2)
(progn
(print "you have chosen two")
(print " Takeaway")))
(if (= value 3)
(print "you have chosen three"))
)
(menu)ITECH5403 ATMC Dr. Haidar AL-Khalidi
10
Ex2:
(defun eating ()
(print "You are in eating function")
(menu)
)
(defun takeaway()
(print "You are in takeaway function")
(menu)
)
(defun menu ()
(format t "~%1: Eating Here~%")
(format t "2: Takeaway~%")
(format t "3: Exit~%")
(format t "-----------~%")
(format t "please select one:~%")
(setq value (read))
(if (= value 1)
(progn
(format t "You have chosen one Eating Here")
(eating)
)
)
(if (= value 2)
(progn
(print "you have chosen two")
(takeaway)))
(if (= value 3)
(progn
(print "you have chosen three"))
) )
(menu)
Run lisp file from commend line (cmd)
1- Put lisp file in the same folder of CLISP.exe
2- Open cmd
3- Navigate to the lisp folder
4- Then type clisp yourfilename.lisp