Using Lisp Lisp is a interactive system You

  • Slides: 57
Download presentation
Using Lisp · Lisp is a interactive system · You can files to be

Using Lisp · Lisp is a interactive system · You can files to be processed as a batch file, but more often than not the programmer is the “main program” · Every expression typed a the “>” prompt is “read” and “evaluated” unless it is prefixed with an apostrophe ‘ · Typing (exit) at the “>” prompt terminates the xlisp program

Go to computer and play with interactive LISP · The best way to learn

Go to computer and play with interactive LISP · The best way to learn Lisp is to go to computer and just play with functions, as you see below. · Please do this.

Sample Output >(a b c) error: unbound function - a if continued: try evaluating

Sample Output >(a b c) error: unbound function - a if continued: try evaluating symbol again 1> [ back to top level ] > '(a b c) > 1 1 > 1. 2 > a error: unbound variable - a if continued: try evaluating symbol again 1> [ back to top level ]

Sample Output > nil > t t > T t > '(a (b c)

Sample Output > nil > t t > T t > '(a (b c) d) > (setq sam 'abc) abc > sam abc

Arithmetic Functions > (/ 2 3) 2/3 > (/ 1. 0 2) 0. 5

Arithmetic Functions > (/ 2 3) 2/3 > (/ 1. 0 2) 0. 5 > (1+ 3) 4 > (mod 2 3) 2 > (mod 5 2) 1 > (+ (* 2 2) (/ 4. 0 5) ) 4. 8

car=first and cdr=rest > (car '(a b c)) a > (cdr '(a b c))

car=first and cdr=rest > (car '(a b c)) a > (cdr '(a b c)) (b c) > (car nil) nil > (cdr nil) nil > (first '(a b c)) a > (car (cdr '(a b c))) b > (cadr '(a b c)) b

List Functions > (list 'a 2 'b) (a 2 b) > (list '(a b)

List Functions > (list 'a 2 'b) (a 2 b) > (list '(a b) '(c d)) sam had a value ‘abc assigned ((a b) (c d)) earlier > (list sam c) error: unbound variable - c if continued: try evaluating symbol again 1> [ back to top level ] > (list sam 'c) (abc c) > (cons 'a '(b c d)) (a b c d) > (cons '(a b c) 'd) ((a b c). d)

List Functions > (append '(a b) '(c d)) (a b c d) > (reverse

List Functions > (append '(a b) '(c d)) (a b c d) > (reverse '(a b c d)) (d c b a) > (length '(a (b c) d))) 3 > > (last '(a b c d)) (d) > (subst 'a 'b '(a b c)) (a a c) > (subst 'a 'b '(a b c b)) (a a c a) Substitutes in list the atom b for atom a

eval and quote > (eval (cdr '(a + 2 3))) cdr creates list (+

eval and quote > (eval (cdr '(a + 2 3))) cdr creates list (+ 2 3) 5 > (setq a 'b) b > a b > b error: unbound variable - b if continued: try evaluating symbol again 1> [ back to top level ] > (set 'a 'b) b > (eval ''a)) b > 'a a

eval and quote > (eval '(quote a))) b > 'a a > (eval '(list

eval and quote > (eval '(quote a))) b > 'a a > (eval '(list '* 9 6)) (* 9 6) > (eval '(list * 9 6))) error: bad function - (* 9 6) 1> [ back to top level ] > (eval '(list '* 9 6))) 54 First eval inside creates a “program with data”, second eval (outside) calculates the value of this “program”

Function Definition > (defun intro (x y) (list x 'this 'is y) ) Intro

Function Definition > (defun intro (x y) (list x 'this 'is y) ) Intro >; be careful not to quote the arguments when >; defining the function > (intro 2 3) (2 this is 3) > (intro 'stanley 'livingston) (stanley this is livingston)

Predicate Functions > (atom 2) t > (atom '(a b c)) nil > (listp

Predicate Functions > (atom 2) t > (atom '(a b c)) nil > (listp 2) nil > (listp '(a b c)) t > (equal 2 3) nil > (= 2 3) nil > (equal 6 (* 2 3)) t

Predicate Functions > (setq a ‘(1 2)) (1 2) > (equal a ‘(1 2))

Predicate Functions > (setq a ‘(1 2)) (1 2) > (equal a ‘(1 2)) t > (eql a ‘(1 2)) nil > (null '()) t > (null 2) nil > (null nil) t

Membership Functions > (member 'c '(a b c d)) (c d) > (member 'a

Membership Functions > (member 'c '(a b c d)) (c d) > (member 'a '((a b) c d)) nil > (member '(d e) '((a b) c (d e) f)) nil > (assoc 'c '((a b) (c d) (e f))) (c d) And now go to computer and check the following functions This member was not using equal inside

Another look at recursion

Another look at recursion

Recursive Functions Our own definitions of functions member and length (defun my-member(element list) (cond

Recursive Functions Our own definitions of functions member and length (defun my-member(element list) (cond ((null list) nil) ((equal element (car list)) list) (t (my-member element (cdr list))))) (defun my-length(list) (cond ((null list) 0) (t (+ (my-length(cdr list)) 1))))

Recursive Functions Counts atoms at all levels of a nested list (defun count-atoms(list) (cond

Recursive Functions Counts atoms at all levels of a nested list (defun count-atoms(list) (cond ((null list) 0) ((atom list) 1) (t (+ (count-atoms (car list)) (count-atoms (cdr list)))))) Compare this pattern with patterns of copy and equal functions; this is binary tree recursion

Linear or cdr recursion (length ‘((1 2) 3 (1 (4 (5))))) 3 + 1

Linear or cdr recursion (length ‘((1 2) 3 (1 (4 (5))))) 3 + 1 (length (3 (1 (4 (5))))) + 1 (length ()) 0

Tree of recursion

Tree of recursion

Temporary Variable Scopes · LET is the Scheme mechanism for temporarily binding values to

Temporary Variable Scopes · LET is the Scheme mechanism for temporarily binding values to names – (LET ( – (name_1 expression_1) – (name_2 expression_2) – <S-expressions> – )) · Evaluate expression_i and bind result to name_i · Name_1 and name_2 can only be used in the <Sexpressions> in the body of the LET – static scoping – name_i can’t have a different value assigned

More of important functions

More of important functions

let and let*

let and let*

How to declare local variables (we are going to need this for iterative functions)?

How to declare local variables (we are going to need this for iterative functions)? (LET ( ( <var 1> <val 1> ). . . ( <vark> <valk> ) ) <exp 1>. . . <exp. N> ) · LET is your way to set up temporary variables. You can initialize each local variable to its value concurrently, then evaluates expressions sequentially. It returns the result of evaluating the last expression. · The default value of local variables declared by LET is NIL.

An Example of LET Is the situation of the party likely to be safe

An Example of LET Is the situation of the party likely to be safe for you ? That is, are there more ‘friends’ then ‘enemies’ at the party! (defun is-safe-p ( guests ) (let ( (friendly-guests nil) (hostile-guests nil) ) ; ; initializations (setq friendly-guests (identify-friends guests)) (setq hostile-guests (identify-enemy guests)) (> (length friendly-guests) (length hostile-guests) ) ; ; are there more friendly than hostile ))

Let* evaluates ALL of the expressions before ANY of the variables are bound. Let*

Let* evaluates ALL of the expressions before ANY of the variables are bound. Let* allows you to evaluate things in the order that they are listed (this is not necessarily true of LET) Example of let*: (let* ((sum (+ 8 3 4 2 7)) ; sum needs value (mean (/ sum 5))) ; ; calculate the mean value (* mean)) ; ; return the mean square ***Most of the time it doesn’t matter, but check this if you keep getting errors.

loop · The simplest form of iteration is the – LOOP (loop (<test condition>

loop · The simplest form of iteration is the – LOOP (loop (<test condition> ) (return <optional var/val>) [body] ) ; end loop

IF and IF-ELSE · We will explore the control forms later, here are four

IF and IF-ELSE · We will explore the control forms later, here are four to get started –if and if-else: » (if (condition) then) » (if (condition) then else) • then – what to return if the condition is true • else – what to return if the condition is false » these will usually be function calls, but could be values to return • (if (/= y 0) (/ x y) 0) – divide x by y or return 0 if y =0

Example Loop (let ((counter 1)) ; initializing my variable (loop (If (= counter 2)

Example Loop (let ((counter 1)) ; initializing my variable (loop (If (= counter 2) (return (+ counter 5)) (+ counter 1) ))) 6 is returned. (loop (<test condition> ) (return <optional var/val>) [body] )

Another Example (defun test ( ) (let ((n 0) (lis nil)) ; initializing (loop

Another Example (defun test ( ) (let ((n 0) (lis nil)) ; initializing (loop (if (> n 10) (return lis) (setq lis (cons n lis))) ; this is end of if (setq n (+ n 1)) ))) => (10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) (loop (<test condition> ) (return <optional var/val>) [body] )

dotimes and dolist

dotimes and dolist

Basic Control Structures –iteration: dotimes and dolist » (dotimes (var num) …) • iterates

Basic Control Structures –iteration: dotimes and dolist » (dotimes (var num) …) • iterates from 0 to num-1, setting var to each value one at a time • (dotimes (i n) (print (+ i 1))) – prints the numbers 1 through n » (dolist (var lis) …) • iterates for each item in the list lis, with var assigned to each • (dolist (a lis) (print a)) – prints each item of lis one at a time

dotimes Use dotimes for a counted loop (dotimes (<var--count> <intobj- upper limit> [retobj>]) <body>)

dotimes Use dotimes for a counted loop (dotimes (<var--count> <intobj- upper limit> [retobj>]) <body>) (defun test () (let ((sum 0)) (dotimes (x 5 sum) ; x var initialized (print x) (print sum) (setq sum (+ sum x))))) to 0; 5 is limit; sum is return

Dolist Use DOLIST to process elements of a list. This is like cdring down

Dolist Use DOLIST to process elements of a list. This is like cdring down the list – recursion! (dolist (<var><list> [<retobj>] <body>) Evaluates <list> ; which must be a list The var is then bound to each item in list Body is executed in order <retobj> optional, is evaluated and returned

Example: Using dolist to calculate a list of squares ele is the running element

Example: Using dolist to calculate a list of squares ele is the running element of the list Reverse the result list lst 2 (defun sq-list (lst 1) before returning (let ((lst 2 nil)) (dolist (ele lst 1 (reverse lst 2) ) ; assigns first element lst 1 to ele – again ; remember that were first/resting through the list. ; will go through each element of lst 1 ; will return the reverse of lst 2 (setq lst 2 (cons (* ele ) Conses square of ele to the beginning of lst 2))))) list lst 2 (sq-list ‘(1 2 3 4) Þ (1 4 9 16) (dolist ( <var> <list> [<retobj>] <body>)

Another example of dolist: (defun greet (people) (dolist (person people) (print (append ‘(so nice

Another example of dolist: (defun greet (people) (dolist (person people) (print (append ‘(so nice to see you) (list person))))) (setq guests ‘(sally bobo mr-potato-head)) (greet guests) -> (so nice to see you sally) (so nice to see you bobo) (so nice to see you mr-potato-head) (dolist ( <var> <list> [<retobj>] <body>)

do

do

Iteration · DO is an iteration construct that allows for local variables · (DO

Iteration · DO is an iteration construct that allows for local variables · (DO ((var init step). . . ) ; ; assign initial values to variables (test expr 1 expr 2. . . ) ; ; evaluate test body 1. . . ) – » if true, evaluate expr 1, expr 2. . . ; return value of last expr as value of DO and terminate » if false, evaluate body 1, body 2, . . . ; evaluate step expressions and assign to vars; re-evaluate test

Iteration · Example: · calculating power M to power N (DO ((var init step).

Iteration · Example: · calculating power M to power N (DO ((var init step). . . ) (test expr 1 expr 2. . . ) body 1. . . ) Initialize RESULT to 1, next multiply it by. M (DEFUN POWER (M N) ; we raise M to power N (DO ( (RESULT 1 (* M RESULT)) ; multiple by M starting from 1 (EXPON N (- EXPON 1)) ) ; subtract one from EXPON until zero ( (ZEROP EXPON) RESULT) ) ) ; NOTE NO BODY!! When variable EXPON is finally zero, return the result

The Do iteration · The DO function · (do ( (<var 1> [<init 1>

The Do iteration · The DO function · (do ( (<var 1> [<init 1> [<step 1>]]) … (<varn [<initn>[stepn>]]) ) (<end-pred><fn>…. . <fm> <retobj >) ; ; test body-exp 1 body-exp 2 [<body>] )

Example of Do Countdown: prints numbers from max to 0 (defun iter (max) (do

Example of Do Countdown: prints numbers from max to 0 (defun iter (max) (do ((num max (- num 1))) ; assign max to num ; subtract 1 from num in loop ((<= num 0) ‘end) ; ; this is end condition. (print num))) (do ( (<var 1> [<init 1> [<step 1>]]) … (<varn [<initn>[stepn>]]) ) (<end-pred><fn>…. . <fm> <retobj >) ; ; test body-exp 1 body-exp 2 [<body>] )

Another example of do Summing all integers from 0 up to max (defun iter-sum

Another example of do Summing all integers from 0 up to max (defun iter-sum (max) (do ((num max (- num 1)) (sum 0 (+ sum num))) [<init 1> [<step 1>]]) ((<= num 0) sum) ; ; ; test (do ( (<var 1> … (<varn [<initn>[stepn>]]) ) ; ; no body (<end-pred><fn>…. . <fm> <retobj >) ; ; test ) body-exp 1 body-exp 2 ) [<body>] ) In English: Assign max to number, and 0 to sum. Each time through the loop, subtract 1 from num and add sum to number. When Number is less than or equal to 0, return sum.

Yet Another example of do (defun reverse-list (ls) ( if (listp ls) (do (

Yet Another example of do (defun reverse-list (ls) ( if (listp ls) (do ( (new-ls () (cons (first old-ls) new-ls)) (old-ls ls (rest old-ls)) ) (do ( (<var 1> [<init 1> [<step 1>]]) ((null old-ls) new-ls) ) … [user]: (reverse-list '(3 1 4 1 5 9)) (9 5 1 4 1 3) (<varn [<initn>[stepn>]]) ) (<end-pred><fn>…. . <fm> <retobj >) ; ; test body-exp 1 body-exp 2 [<body>] ) With do function, you probably don’t need a let --because it’s in the do function.

eval, apply and funcall

eval, apply and funcall

EVAL · (EVAL <exp>) invokes the evaluation procedure. > (EVAL (LIST ‘+ 4 5))

EVAL · (EVAL <exp>) invokes the evaluation procedure. > (EVAL (LIST ‘+ 4 5)) 9 > (SETQ A ‘X) Value of atom A is atom X X > (SETQ X 100) Value of atom X is 100 > (CONS (EVAL A) (CONS A ‘( A ) ) ) ? (100 X A) Value of (EVAL A) is value of A which is value of atom X which is 100

Using EVAL to create fn at run-time Create a function to recognize cups based

Using EVAL to create fn at run-time Create a function to recognize cups based on the description learned: We define function create-cup-recognizer (defun create-cup-recognizer ( cup-description ) (eval (list ‘defun ‘cup-recognizer ‘( obj ) (list ‘subset Which defines function eval actually (list ‘quote cup-description) creates the cup-recognizer definition ‘obj ) ) (defun cup-recognizer (obj ) ) (subset (quote cup-description) obj) ) subset tests whether the first arg is a subset of the second arg. > (create-cup-recognizer cup-def) cup-recognizer

What if we want to apply a function to an entire list? (MAPCAR <fn-name>

What if we want to apply a function to an entire list? (MAPCAR <fn-name> <arg 1 -list> <arg 2 -list>) > (MAPCAR ‘+ ‘(1 2 3 4) ‘(100 200 300 400) ) (101 202 303 404) > (SETQ action ‘drunk) DRUNK > (SETQ hostile-guests (identify-enemy guests)) Ø (MAPCAR action hostile-guests) Ø Write your own functions identify-enemy and action

APPLY · (APPLY <fn-name> <arg-list> ) >(APPLY ‘CONS ‘( A ( B C )

APPLY · (APPLY <fn-name> <arg-list> ) >(APPLY ‘CONS ‘( A ( B C ) ) ) (A B C) > (APPLY ‘CAR ‘( (A B C) ) ) A > (SETQ OP ‘+) + > (APPLY OP ‘( 5 3 ) ) 8 > (SETQ OP ‘-) Ø (APPLY OP ‘( 5 3 ) ) 2

A Better Example of APPLY Suppose we want to ``do something’’ to an enemy

A Better Example of APPLY Suppose we want to ``do something’’ to an enemy identified, but the action is determined at run time (based on their actions, degree of threats, etc. ). (defun action (fn enemy) fn (cons enemy nil) ) ) (defun seize (person). . ) (defun kill (person). . . ) (defun drunk (person). . . ) > (action ‘seize ‘Black. Knight ) (APPLY

FUNCALL -- A sibling of APPLY · (FUNCALL <fn-name> <arg 1> <arg 2>. .

FUNCALL -- A sibling of APPLY · (FUNCALL <fn-name> <arg 1> <arg 2>. . . ) >(FUNCALL ‘CONS ‘A ‘( B C ) ) (A B C) > (FUNCALL ‘CAR ‘(A B C) ) A > (SETQ OP ‘+) + > (FUNCALL OP 5 3 ) 8 > (SETQ OP ‘-) > (FUNCALL OP 5 3 )

Useful help facilities · (apropos ‘str) list of symbols whose name contains ‘str ·

Useful help facilities · (apropos ‘str) list of symbols whose name contains ‘str · (describe ‘symbol) description of symbol · (describe #’fn) description of function · (trace fn) print a trace of fn as it runs · : a abort one level out of debugger

A Lisp example: Fibonacci Numbers · Writing a function to compute the nth Fibonacci

A Lisp example: Fibonacci Numbers · Writing a function to compute the nth Fibonacci number – Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13, … » fib(0) = 0 » fib(1) = 1 » fib(n) = fib(n-2) + fib(n-1)

Complete Version (defun fib (n) (cond ((eql n 0) ((eql n 1) (t (+

Complete Version (defun fib (n) (cond ((eql n 0) ((eql n 1) (t (+ (fib 0) ; base case 1) ; base case (- n 1)) ; recursively compute fib(n) (- n 2))))))

Examples: Roulette Wheel (DEFUN roulette-wheel (bet-1 bet-2) (compare-with-bet (RANDOM 37) bet-1 bet-2)) (DEFUN compare-with-bet

Examples: Roulette Wheel (DEFUN roulette-wheel (bet-1 bet-2) (compare-with-bet (RANDOM 37) bet-1 bet-2)) (DEFUN compare-with-bet (wheel-spin bet-1 bet-2) (IF (OR (= wheel-spin bet-1) (= wheel-spin bet-2)) (DISPLAY “You won! ”) (DISPLAY “You lost! “)) wheel-spin) (RANDOM X) is a built-in function that returns a value between 0 and X (compare-with-bet) returns wheel-spin as a value (the last s-expression evaluated)

Examples: leap year, length (DEFUN leap-year? (year) (COND ((divisible? year 400) #t) ((divisible? year

Examples: leap year, length (DEFUN leap-year? (year) (COND ((divisible? year 400) #t) ((divisible? year 100) #f) ((divisible? year 4) #t) (ELSE #f))) (DEFUN length list-of-objects) (COND ((NULL list-of-objects) 0) (ELSE (1+ (length (CDR list-of-objects))))) Can use T or any atom

Examples (continued) (DEFUN maximum (list-nums) (COND ((NULL (CDR list-nums))(CAR list-nums)) (ELSE (LET ((maxtail (maximum

Examples (continued) (DEFUN maximum (list-nums) (COND ((NULL (CDR list-nums))(CAR list-nums)) (ELSE (LET ((maxtail (maximum (CDR list-nums))) (first (CAR list-nums))) (IF (> first maxtail))))) use recursion to find maximum value in CDR of list, list compare to first value in list - maximum is larger of those two

Examples (continued) (DEFUN inc-list (list-nums) (COND ((NULL list-nums) NIL) (ELSE (CONS (1+ (CAR list-nums))

Examples (continued) (DEFUN inc-list (list-nums) (COND ((NULL list-nums) NIL) (ELSE (CONS (1+ (CAR list-nums)) (inc-list (CDR list-nums)) ) ) returns a new list containing all the values of the argument list incremented by 1

Sources Bruce R. Maxim Kathleen Swigger Ron Danielsen

Sources Bruce R. Maxim Kathleen Swigger Ron Danielsen