LISP returns 5. But now if you type5
LISP returns:foo
Error: The variable FOO is unbound Error signalled by EVAL
Now if you type
LISP returns:(+ 1 2)
3
LISP returns 5. If you type5
LISP returns “foo”“foo”
LISP returns:foo
Error: the variable FOO is unbound
open-paren operator arguments close-paren ( + 1 2 )
(+ 1 2)
(+ (* 2 3) (- 5 2))
(absolute-value 4) (list 1 2 3) (doctor)
()
x l (note that this is different from the number 1) list a-real-long-variable var5
2.3 -3 -3.2 3e4
(setq x 5)
LISP returns 5. But now if you type
x
LISP returns 5 also.
(+ x 3)
(setq y 5) (setq y (1+ 4)) (setq y x) this assumes that x has been bound to 5 beforehand (setq y (/ (+ x 5) 2))
(let ((a 2)) (+ a 1))
(setq a 1) (+ a 1) (let ((a 2)) (+ a 1)) (+ a 1)
(let ((a (+ 3 4))) (- a 2))
The value that a is bound to is 7. And so the value of (- a 2) is 5, which is the value of the whole expression.
(let ((a 1) (b 2)) (+ a b))
Binds a to 1 and b to 2 and then adds them up. So this yields 3.
(setq a 1) (let ((b 2)) (+ a 1))
In this case a has a top-level binding to 1 and the let form binds b but not a. So the value that is used for a is the global value namely 1, so the value of the expression is 2.
(let ((b 2)) (+ a b))
In this case the value of b is obtained from the local environment, and the value of a is obtained from the top-level environment, so the result is 3.
(let ((a 1)) (let ((b 2)) (+ a b)))
In this case the outer let form binds a to 1. A let form can contain any LISP expression as its body. So there is nothing wrong with putting another let form in the body. This let form binds b to 2. The body of the inner form is (+ a b).
(> 3 2)
returns
t
(> 2 3)
returns
nil
Predicate | Description |
---|---|
< | less than This is the opposite of > |
= | equals This operator returns t if its two arguments are numerically equal, nil otherwise. |
<= | less than or equal |
>= | greater than or equal |
(add-one (add-one 10)) 12
(defun positive (x) (>= x 0))
(defun twice (x y) (= x (* 2 y)))
When we call twice
with these arguments:
(twice 4 2)
The body is
(= x (* 2 y))
Where x is bound to 4 and y is bound to 2. So (* 2 y) returns 4, and x is 4, and = returns t, so twice returns t.
(defun zerop (x) (= x 0)) (defun plusp (x) (> x 0)) (defun minusp (x) (< x 0))
(if (> 3 2) 1 2)
(defun zun (arg) (if (= arg 0) 0 1))
So what happends if we call
(zun 3)
If we call(defun max (x y) (if (> x y) x y))
(max 7 7)
Then the condition is nil (because 7 is not greater than 7), so the second consequent is evaluated. This returns 7. numbers.
(defun distance (a b) (if (> a b) (- a b) (- b a)))
As in the case of max, if a and b are equal, then we end up subtracting b from a, but we would have gotten 0 in either case.
(not t) nil(not nil) T
(not (= 3 4)) T (and t t t) T
(and t nil t) nil
(and (= 1 1) (= 2 2)) T (or nil nil nil) nil
(or t t) T
(or (= 1 2) (> 5 4)) T
(defun either-zero (x y) (or (= x 0) (= y 0))) (defun in-ten (x) (if (and (> x 0) (< x 10)) x 5))
x! = x (x-1) (x-2) ...
So,
3! = 3*2*1 = 6 5! = 5*4*3*2*1 = 120
(defun fact (x) (if (= x 0) 1 (* x (fact (1- x)))))
power
. The
power
function raises some number to a power by
multiplying the number times itself some number of times.
(defun power (x n) (if (= n 0) 1 (* x (power x (1- n)))))
power
function for the same value of x, and one
less than the value of n. The result is then multiplied by
x to yield the power
function for this value of
x and n.
cond
is the most general conditional in
LISP. Where if
and when
and
unless
allow only a single test, cond
allows
any number. Here is an example use of cond
:
(defun frab (x y) (cond ((< x y) (+ x y)) ((= x y) 0) (t (* x y))))
cond
expression begins with the operator
cond
. This is followed by a sequence of
statements each enclosed in parentheses.
cond
statement begins with a condition and is
followed by any number of consequent forms.
cond
is:
((< x y) (+ x y))
(< x y)
and the single
consequent form is (+ x y)
.
cond
is interpreted is as follows: The
interpreter works on the statements in order. As it gets to each
statement, the condition part is evaluated. If it returns
t
, the consequent forms are evaluated, and the
value of the last consequent form is the value of the
cond
. Once the condition part of a statement returns
t
, and the associated consequents are evaluated,
no more statement forms are considered. If no condition part of a
statement in a cond
returns t
, the
value of the cond
is nil
.
Could be written like this:(if < test> < true-consequent> < false-consequent>)
For example:(cond ((< test> < true-consequent>) (t < false-consequent>)))
Could be written:(if (> x y) (- x y) (- y x))
(cond ((> x y) (- x y)) (t (- y x)))
If you type
(setq list-1 (list 1 2 3))
LISP returns
(1 2 3)
(setq list-2 (list (+ 1 2) (- 5 3) (* 2 5) 7)) (3 2 10 7)
(first list-1) 1
(second list-1) 2
(third list-1) 3
The function rest takes a single argument which is a list, and returns a list which the same as the original list, except that it doesn't include the first element:
(rest list-1) (2 3)
(first (rest list-1)) 2 (rest (rest list-1)) (3) (rest (rest (rest list-1))) nil
(defun second (ls) (first (rest ls)))
first = car rest = cdr
(listp list-1) t(listp (rest list-1)) t
And nil is considered a list also:
(listp nil) t
listp only returns t for lists:
(listp 4) nil(listp t) nil
(atom 6) t(atom t) t
(atom (list 1 2 3)) nil
(defun non-nil-list (x) (and (listp x) (not (null x))))
(setq list-1 (list 1 2 3))(setq list-2 (cons 0 list-1)) (0 1 2 3)
list-1 (1 2 3)
But the new list has the additional element:
list-2 (0 1 2 3)
(cons 1 nil) (1)
This is the same result as if you typed:
(list 1) (1)
(listp (list 1)) => t (listp 1) => nil
(cons 1 (cons 2 (cons 3 nil))) (1 2 3)
----------------- | | | | first | rest | | (car) | (cdr) | -----------------
(setq c-1 (cons 'a nil)) => (a)
would be drawn like this:
----------------- | | | | a | nil | | | | -----------------
And this makes sense because if you typed
(first c-1) => a (rest c-1) => nil
(setq c2 (cons 'w (cons 'x nil))) => (w x)
looks like this:
---------------- | | | | w | * | | | | | -----------|---| | V ---------------- | | | | x | nil | | | | ----------------
So here we have two cons cells. The first cons cell has a first which is the symbol w, the rest of that points to another cons cell whose first is the symbol x and whose second is nil.
---------------- | | | | w | * | | | | | -----------|---| | V ---------------- | | | | x | * | | | | | -----------|---| | V ---------------- | | | | y | nil | | | | ----------------
This structure corresponds to what you would get by evaluating:
(cons 'w (cons 'x (cons 'y nil)))
Note that this is the same as what you would get by evaluating
(list 'w 'x 'y)
or
'(w x y)
(setq c3 '((a b) c))
That this correspond to what would be constructed by:
(cons (cons 'a (cons 'b nil)) (cons 'c nil))
And this helps us draw the diagram:
---------------- ---------------- | | | | | | | * | *----------> | c | nil | | | | | | | | ----|----------| ---------------- | V ---------------- | | | | a | * | | | | | -----------|---| | V ---------------- | | | | b | nil | | | | ----------------
(setq list-1 '(a b c)) (setq list-2 '(a b c))(eql list-1 list-2) nil
Even though both of them look the same: (a b c).
But a list is eql to itself:
(eql list-1 list-1) t(eql list-2 list-2) t
(defun equal-1 (a b) (cond ((eql a b) t) ((atom a) nil) ((atom b) nil) ((eql (first a) (first b)) (equal-1 (rest a) (rest b)))))
(equal '((a b) (c) d) '((a b) (c) d))
And have it return t.
(defun equal (a b) (cond ((eql a b) t) ((atom a) nil) ((atom b) nil) ((equal (first a) (first b)) (equal (rest a) (rest b)))))