# COMMON LISP: A GENTLE INTRODUCTION TO SYMBOLIC COMPUTATION - PowerPoint PPT Presentation

1 / 45

COMMON LISP: A GENTLE INTRODUCTION TO SYMBOLIC COMPUTATION. David S. Touretzky. INTRODUCTION . THE EVAL FUNCTION. The EVAL function is the heart of Lisp. EVAL 's job is to evaluate Lisp expressions to compute their result. Some example EVAL function: ( + 1 6)  7

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

COMMON LISP: A GENTLE INTRODUCTION TO SYMBOLIC COMPUTATION

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

## COMMON LISP:A GENTLE INTRODUCTIONTO SYMBOLIC COMPUTATION

David S. Touretzky

## INTRODUCTION

### THE EVAL FUNCTION

• The EVAL function is the heart of Lisp.

• EVAL's job is to evaluate Lisp expressions to compute their result.

• Some example EVAL function:

(+ 1 6)  7

(oddp (+ 1 6))  T

(* 3 (+ 1 6))  21

(/ (* 2 11) (+ 1 6))  22/7

(not (equal 5 6))  T

ODDP : returns T if the input number is odd

EVENP: returns T if the input number is even

### EXERCISES

• What does (NOT (EQUAL 3 (ABS -3))) evaluate to?

• Write an expression in EVAL notation to add 8 to 12 and divide the result by 2.

### DEFINING FUNCTIONS IN EVAL NOTATION

• The AVERAGE function is defined in EVAL notation this way:

(defun average (x y)

(/ (+ x y) 2.0))

• Another example of function definition with DEFUN:

(defun square (n) (* n n))

• A function that computed the total cost of a merchandise order might name its arguments QUANTITY, PRICE, and HANDLING-CHARGE.

(defun total-cost (quantity price handling-charge)

(+ (* quantity price) handling-charge))

### EXERCISES

• Define a function PYTHAG that takes two inputs, x and y, and returns the square root of x2+y2. You may recognize this as Pythagoras's formula for computing the length of the hypotenuse of a right triangle given the lengths of the other two sides. (PYTHAG 3 4) should return 5.0.

### USING SYMBOLS AND LISTS AS DATA

• In EVAL notation symbols are used to name variables, so if we write

(equal kirk spock)

• Lisp will think we are trying to compare the value of the global variable named KIRK with the value of the global variable named SPOCK.

• Since we haven't given any values to these variables, this will cause an error:

(equal kirk spock)  Error! variable KIRK has no value.

• We can tell Lisp to treat KIRK and SPOCK as data rather than as variable references by putting a quote before each one.

(equal 'kirk 'spock)  nil

• Because the symbols T and NIL evaluate to themselves, they don't need to be quoted to use them as data.

(list 'james t 'kirk)  (james t kirk)

### USING SYMBOLS AND LISTS AS DATA

• For examples:

(defun riddle (x y)

(list 'why 'is 'a x 'like 'a y))

(riddle 'raven 'writing-desk)  (why is a raven like a writing-desk)

• Lists also need to be quoted to use them as data; otherwise Lisp will try to evaluate them, which typically results in an ''undefined function'' error.

(first (we hold these truths))  Error! undefined function WE.

(first '(we hold these truths))  we

(third (my aunt mary)) Error! undefined function MY.

(third '(my aunt mary)) mary

(+ 1 2)  3

'(+ 1 2)  (+ 1 2)

### why is a raven like a writing-desk

• 鳥鴉為什麼長得像書桌 Why is a raven like a writing-desk，在原作書裡並沒有解答，但各地的愛麗絲書迷公認的最佳答案是Because there is a b in both為何最佳，因為這是一個無聊而正確的肯定句，正好用來回覆那個無聊而正確的疑問句，恰好raven和writing-desk兩個字裡面都沒有b，才使得後面那個肯定句變成絕妙的回答，否則這一問一答就有了〈意義〉一但有意義就破壞了它原本的〈無聊〉旨趣，就變的無趣了，而後者之所以正碓，是因為both裡的確有一個b，是不是這樣？這個文字遊戲的意義就在於它沒有意義取自商周出版社 愛麗絲夢遊仙境一書

### THE PROBLEM OF MISQUOTING

• Some examples:

(list 'a 'b c) Error! C unassigned variable.

(list 'a 'b 'c) (a b c)

(cons 'a (b c)) Error! B undefined function. ; cons: constitute

(cons 'a '(b c)) (a b c)

(+ 10 '(- 5 2)) Error! Wrong type input to +.

(+ 10 (- 5 2)) 13

('foo 'bar 'baz) Error! 'FOO undefined function.

'(foo bar baz) (foo bar baz)

### THREE WAYS TO MAKE LISTS

• We have three ways to make lists using EVAL notation.

(1) '(foo bar baz) (foo bar baz)

(2) (list 'foo 'bar 'baz) (foo bar baz)

(3) (cons 'foo '(bar baz)) (foo bar baz)

• Compare the following examples:

(list 33 'squared 'is (* 33 33)) (33 squared is 1089)

'(33 squared is (* 33 33)) (33 squared is (* 33 33))

(list foo bar baz) Error! FOO unassigned variable.

(foo bar baz) Error! FOO undefined function.

('foo 'bar 'baz) Error! 'FOO undefined function.

### EXERCISES

• The following expressions evaluate without any errors. Write down the results.

(cons 5 (list 6 7))

(cons 5 '(list 6 7))

(list 3 'from 9 'gives (- 9 3))

(+ (length '(1 foo 2 moo)) (third '(1 foo 2 moo)))

(rest '(cons is short for construct))

• Study this function definition:

(defun call-up (caller callee)

(list 'hello callee 'this 'is caller 'calling))

How many arguments does this function require? What are the names of the arguments? What is the result of (CALL-UP 'FRED 'WANDA)?

### FOUR WAYS TO MISDEFINE A FUNCTION

• An example:

(defun intro (x y) (list x 'this 'is y))

(intro 'stanley 'livingstone)  (stanley this is livingstone)

• Four ways to misdefine a function:

• The first way to misdefine a function is to put something other than plain(清楚的), unadorned(樸素的)symbols in the function's argument list.

(defun intro ('x 'y) ; bad argument list

(list x 'this 'is y))

(defun intro ((x) (y)) ; bad argument list

(list x 'this 'is y))

• The second way to misdefine a function is to put parentheses around variables where they appear in the body.

### FOUR WAYS TO MISDEFINE A FUNCTION

• The second way to misdefine a function is to put parentheses around variables where they appear in the body.

(defun intro (x y) (list (x) 'this 'is (y)))

(intro 'stanley 'livingstone)  Error! X undefined function.

• The third way to misdefine a function is to quote a variable. Symbols must be left unquoted when they refer to variables.

(defun intro (x y) (list 'x 'this 'is 'y))

(intro 'stanley 'livingstone) (x this is y)

• The fourth way to misdefine a function is to not quote something that should be quoted. In the INTRO function, the symbols X and Y are variables but THIS and IS are not.

(defun intro (x y) (list x this is y))

(intro 'stanley 'livingstone) Error! THIS unassigned variable.

• Consider the DOUBLE function, which creates a variable named N every time we call it:

(defun double (n) (* n 2))

• Now let‘s try an example with two variables. Here is a definition for QUADRUPLE(四倍數) in terms of DOUBLE:

(defun quadruple (n) (double (double n)))

• Evaluate the expression (QUADRUPLE 5)

### EXERCISES

• Consider the following function, paying close attention to the quotes:

(defun scrabble (word)

(list word 'is 'a 'word))

• The symbol WORD is used two different ways in this function. What are they?

• What is the result of (SCRABBLE 'AARDVARK)?

• What is the result of (SCRABBLE 'WORD)?

• Here's a real confuser:

(defun stooge (larry moe curly)

(list larry (list 'moe curly) curly 'larry))

• What does the following evaluate to? It will help to write down what value each variable is bound to and, of course, mind the quotes!

(stooge 'moe 'curly 'larry)

### LIST EXAMPLE

• An example:

(defun long-function (some-list)

(cons (third some-list)

(list (second some-list)

(fourth some-list)

(first some-list))))

Break 4 [8]> (long-function '( a b c d))

(C B D A)

Break 4 [8]> (long-function '( a b c d e f))

(C B D A)

### EXERCISES

• Here is an example of the function MYFUN, a strange function of two inputs.

(myfun 'alpha 'beta) ((ALPHA) BETA)

• Write MYFUN.

• Test your function to make certain it works correctly.

• What is wrong with this function? What does (FOO 5) do?

(defun foo (x) (+ 1 (zerop x)))

### FUNCTIONS OF NO ARGUMENTS

• Suppose we wanted to write a function that multiplies 85 by 97.

• Notice that this function requires no inputs.

• Since the function doesn't take any inputs, it will have an empty argument list.

• The empty list, of course, is NIL.

• Let's define this function under the name TEST:

(defun test () (* 85 97))

• After doing this, we see that

(test)  8245

(test 1)Error! Too many arguments.

### THE QUOTE SPECIAL FUNCTION

• QUOTE is a special function: Its input does not get evaluated.

• The QUOTE special function simply returns its input.

• For example:

(quote foo) foo

(quote (hello world)) (hello world)

• (cons 'up '(down sideways)) is equal to (cons (quote up) (quote (down sideways)))

• The first quote is stripped away by the evaluation process, but any extra quotes remain.

'foofoo

''foo  'foo also written (quote foo)

(list 'quote 'foo) (quote foo) also written 'foo

(first ''foo) quote

(rest ''foo) (foo)

(length ''foo)  2

### EVAL AND APPLY

• EVAL is a Lisp primitive function.

• Each use of EVAL gives one level of evaluation.

'(+ 2 2) (+ 2 2)

(eval '(+ 2 2)) 4

'''boing ''boing

(eval '''boing) 'boing

(eval (eval '''boing) boing

(eval (eval (eval '''boing)))  Error! BOING unassigned variable.

'(list '* 9 6)) (list '* 9 6)

(eval '(list '* 9 6)) (* 9 6)

(eval (eval '(list '* 9 6))) 54

### EVAL AND APPLY

• APPLY is also a Lisp primitive function.

• APPLY takes a function and a list of objects as input.

• It invokes (造成) the specified function with those objects as its inputs.

• The first argument to APPLY should be quoted with #' rather than an ordinary quote; #' is the proper way to quote functions supplied as inputs to other functions.

(apply #‘+ ’(2 345)) 14

(apply #'equal '(12 17)) nil

• The objects APPLY passes to the function are not evaluated first.

• In the following example, the objects are a symbol and a list.

• Evaluating either the symbol AS or the list (YOU LIKE IT) would cause an error.

(apply #'cons '(as (you like it))) (as you like it)

### EXERCISES

• What do each of the following expressions evaluate to?

(list 'cons t nil)

(eval (list 'cons t nil))

(eval (eval (list 'cons t nil)))

(apply #'cons '(t nil))

(eval nil)

(list 'eval nil)

(eval (list 'eval nil))

### THE IF SPECIAL FUNCTION

• IF is the simplest Lisp conditional.

• Conditionals are always macros or special functions, so their arguments do not get evaluated automatically.

• The IF special function takes three arguments: a test, a true-part, and a false-part.

• If the test is true, IF returns the value of the true-part.

• If the test is false, it skips the true-part and instead returns the value of the false-part.

• Here are some examples.

(if (oddp 1) 'odd 'even) odd

(if (oddp 2) 'odd 'even) even

(if t 'test-was-true 'test-was-false)  test-was-true

(if nil 'test-was-true 'test-was-false)  test-was-false

(if (symbolp 'foo) (* 5 5) (+ 5 5)) 25

(if (symbolp 1) (* 5 5) (+ 5 5)) 10

### THE IF SPECIAL FUNCTION

• Use IF to construct a function that takes the absolute value of a number.

(defun my-abs (x)

(if (< x 0) (- x) x))

> (my-abs -5);True-part takes the negation.

5

> (my-abs 5) ;False-part returns the number unchanged.

5

### THE IF SPECIAL FUNCTION

• Here's another simple decision-making function.

• SYMBOL-TEST returns a message telling whether or not its input is a symbol.

(defun symbol-test (x)

(if (symbolp x) (list 'yes x 'is 'a 'symbol)

(list 'no x 'is 'not 'a 'symbol)))

> (symbol-test 'rutabaga) ;Evaluate true-part.

(YES RUTABAGA IS A SYMBOL)

> (symbol-test 12345) ;Evaluate false-part.

(NO 12345 IS NOT A SYMBOL)

• IF can be given two inputs instead of three, in which case it behaves as if its third input (the false-part) were the symbol NIL.

(if t 'happy) happy

(if nil 'happy) nil

### EXERCISES

• Write a function MAKE-EVEN that makes an odd number even by adding one to it. If the input to MAKE-EVEN is already even, it should be returned unchanged.

• Recall the primitive function NOT: It returns NIL for a true input and T for a false one. Suppose Lisp didn't have a NOT primitive. Show how to write NOT using just IF and constants (no other functions). Call your function MY-NOT.

• Write a function ORDERED that takes two numbers as input and makes a list of them in ascending order. (ORDERED 3 4) should return the list (3 4). (ORDERED 4 3) should also return (3 4), in other words, the first and second inputs should appear in reverse order when the first is greater than the second.

### THE COND MACRO

• COND is the classic Lisp conditional. Its input consists of any number of test-and-consequent clauses.

• The simplified form is:

(COND (test-1 consequent-1)

(test-2 consequent-2)

(test-3 consequent-3)

....

(test-n consequent-n))

### THE COND MACRO

• Use COND to write a function COMPARE that compares two numbers.

• If the numbers are equal, COMPARE will say ''numbers are the same.''

• If the first number is less than the second, it will say ''first is smaller.''

• If the first number is greater than the second, it will say ''first is bigger.''

• Each case is handled by a separate COND clause.

(defun compare (x y)

(cond ((equal x y) 'numbers-are-the-same)

((< x y) 'first-is-smaller)

((> x y) 'first-is-bigger)))

(compare 3 5) first-is-smaller

(compare 7 2) first-is-bigger

(compare 4 4) numbers-are-the-same

### USING T AS A TEST

• One of the standard tricks for using COND is to include a clause of form

(T consequent)

• The test T is always true, so if COND ever reaches this clause, it is guaranteed to evaluate the consequent(隨後發生的事).

• For example:

• The following function returns the country in which a given city is.

• If the function doesn't know a particular city, it returns the symbol UNKNOWN.

(defun where-is (x)

(cond ((equal x 'paris) 'france)

((equal x 'london) 'england)

((equal x 'beijing) 'china)

(t 'unknown)))

(where-is 'london) england

(where-is 'beijing) china

(where-is 'hackensack) unknown

### EXERCISES

• We can translate any IF expression into a COND expression:

(IF test true-part false-part)

(COND (test true-part)

(T false-part))

Write a version of the absolute value function MY-ABS using COND instead of IF.

### TWO MORE EXAMPLES OF COND

• EMPHASIZE changes the first word of a phrase from ''good'' to ''great,'' or from ''bad'' to ''awful,'' and returns the modified phrase:

(defun emphasize (x)

(cond ((equal (first x) 'good) (cons 'great (rest x)))

((equal (first x) 'bad) (cons 'awful (rest x)))))

(emphasize '(good mystery story)) (great mystery story)

(emphasize '(mediocre mystery story)) nil

(defun emphasize2 (x)

(cond ((equal (first x) 'good) (cons 'great (rest x)))

((equal (first x) 'bad) (cons 'awful (rest x)))

(t x)))

(emphasize2 '(good day))  (great day)

(emphasize2 '(long day)) (long day)

### TWO MORE EXAMPLES OF COND

• Function COMPUTE takes three inputs.

• If the first input is the symbol SUM-OF, the function returns the sum of the second and third inputs.

• If it is the symbol PRODUCT-OF, the function returns the product of the second and third inputs.

• Otherwise it returns the list (THAT DOES NOT COMPUTE).

(defun compute (op x y)

(cond ((equal op 'sum-of) (+ x y))

((equal op 'product-of) (* x y))

(t '(that does not compute))))

(compute 'sum-of 3 7)10

(compute 'product-of 2 4)8

(compute 'zorch-of 3 1) (that does not compute)

### EXERCISES

• Type in the following suspicious (可疑的) function definition:

(defun make-odd (x)

(cond (t x)

((not (oddp x)) (+ x 1))))

What is wrong with this function? Try out the function on the numbers3, 4, and -2. Rewrite it so it works correctly.

• Write a function CONSTRAIN that takes three inputs called X, MAX,and MIN.

• If X is less than MIN, it should return MIN; if X is greaterthan MAX, it should return MAX.

• Otherwise, since X is between MINand MAX, it should return X.

• (CONSTRAIN 3 -50 50) should return 3.(CONSTRAIN 92 -50 50) should return 50. Write one version usingCOND and another using nested IFs.

### THE AND AND OR MACROS

• Suppose we want apredicate for small (no more than two digit) positive odd numbers.

• We canuse AND to express this conjunction of simple conditions:

(defun small-positive-oddp (x)

(and (< x 100)

(> x 0)

(oddp x)))

• Suppose we want a function GTEST that takes two numbers as inputand returns T if either the first is greater than the second or one of them iszero.

• These conditions form a disjunctive set; only one need be true forGTEST to return T. OR is used for disjunctions.

(defun gtest (x y)

(or (> x y)

(zerop x)

(zerop y)))

### EVALUATING AND AND OR

• AND and OR have slightly different meanings in Lisp than they do in logic orin English.

• The precise rule for evaluating AND is:

• Evaluate the clauses oneat a time.

• If a clause returns NIL, stop and return NIL; otherwise go on to thenext one.

• If all the clauses yield non-NIL results, return the value of the lastclause.

• Examples:

(and nil t t) nil

(and 'george nil 'harry) nil

(and 'george 'fred 'harry) harry

(and 1 2 3 4 5) 5

### EVALUATING AND AND OR

• The rule for evaluating OR is:

• Evaluate the clauses one at a time.

• If aclause returns something other than NIL, stop and return that value; otherwisego on to the next clause, or return NIL if none are left.

• Examples:

(or nil t t) t

(or 'george nil 'harry) george

(or 'george 'fred 'harry) george

(or nil 'fred 'harry) fred

### EXERCISES

• What results do the following expressions produce? Read theevaluation rules for AND and OR carefully before answering.

(and 'fee 'fie 'foe)

(or 'fee 'fie 'foe)

(or nil 'foe nil)

(and 'fee 'fie nil)

(and (equal 'abc 'abc) 'yes)

(or (equal 'abc 'abc) 'yes)

### BUILDING COMPLEX PREDICATES

• The HOW-ALIKE function compares two numbers several different ways tosee in what way they are similar.

• It uses AND to construct complex predicatesas part of a COND clause:

(defun how-alike (a b)

(cond ((equal a b) 'the-same)

((and (oddp a) (oddp b)) 'both-odd)

((and (not (oddp a)) (not (oddp b)))'both-even)

((and (< a 0) (< b 0)) 'both-negative)

(t 'not-alike)))

(how-alike 7 7) the-same

(how-alike 3 5) both-odd

(how-alike -2 -3) both-negative

(how-alike 5 8) not-alike

### BUILDING COMPLEX PREDICATES

• The SAME-SIGN predicate uses a combination of AND and OR to test ifits two inputs have the same sign:

(defun same-sign (x y)

(or (and (zerop x) (zerop y))

(and (< x 0) (< y 0))

(and (> x 0) (> y 0))))

• SAME-SIGN returns T if any of the inputs to OR returns T.

• Each of theseinputs is an AND expression.

• The first one tests whether X is zero and Y iszero, the second tests whether X is negative and Y is negative, and the thirdtests whether X is positive and Y is positive.

• Examples:

(same-sign 0 0) t

(same-sign -3 -4) t

(same-sign 3 4) t

(same-sign -3 4) nil

### EXERCISES

• Write a function that squares a number if it is odd and positive, doublesit if it is odd and negative, and otherwise divides the number by 2.

• Write a predicate that returns T if the first input is either BOY or GIRLand the second input is CHILD, or the first input is either MAN orWOMAN and the second input is ADULT.

### WHY AND AND OR ARE CONDITIONALS

• Why are AND and OR classed as conditionals instead of regular functions?

• The reason is that they are not required to evaluate every clause.

• For example, consider the POSNUMP predicate:

(defun posnump (x)

(and (numberp x) (plusp x)))

• POSNUMP returns T if its input is a number and is positive.

• The built-in PLUSP predicate can be used to tell if a number is positive, but if PLUSP is used on something other than a number, it signals a ''wrong type input'' error, so it is important to make sure that the input to POSNUMP is a number before invoking PLUSP.

• If the input isn't a number, we must not call PLUSP.

• Here is an incorrect version of POSNUMP:

(defun faulty-posnump (x)

(and (plusp x) (numberp x)))

### POSNUMPAND FAULTY-POSNUMP

Break 7 [8]> (posnump 3)

T

Break 7 [8]> (posnump -3)

NIL

Break 7 [8]> (posnump 'a)

NIL

Break 8 [9]> (faulty-posnump -3)

NIL

Break 8 [9]> (faulty-posnump 3)

T

Break 8 [9]> (faulty-posnump 'a)

*** - PLUSP: A is not a real number

The following restarts are available:

USE-VALUE :R1 Input a value to be used instead.

ABORT :R2 Abort debug loop

ABORT :R3 Abort debug loop

ABORT :R4 Abort debug loop

ABORT :R5 Abort debug loop

ABORT :R6 Abort debug loop

ABORT :R7 Abort debug loop

ABORT :R8 Abort debug loop

ABORT :R9 Abort main loop

### BOOLEAN FUNCTIONS

• Boolean functions are functions whose inputs and outputs are truth values, meaning T or NIL.

• Another name for boolean functions is logical functions, since they use the logical values true and false.

• Let's define a two-input LOGICAL-AND function:

(defun logical-and (x y) (and x y t))

• This ordinary function differs from the AND macro in several respects.

(logical-and 'tweet 'woof) t

(and 'tweet 'woof) woof

(and (numberp 'fred) (oddp 'fred)) nil

(logical-and (numberp 'fred) (oddp 'fred)) Error! FRED wrong type input to ODDP.

• The expression (ODDP 'FRED) causes an error for LOGICAL-AND but not for AND, because AND never evaluates the second clause.

### EXERCISES

• Write LOGICAL-OR. Make sure it returns only T or NIL for its result.