Presentation is loading. Please wait.

Presentation is loading. Please wait.

Programming Languages I LISP

Similar presentations


Presentation on theme: "Programming Languages I LISP"— Presentation transcript:

1 Programming Languages I LISP
© 1996 by Matthew Smosna June 23, 1996

2 LISP LISP = LISt Processing language
Motivation: language for Artificial Intelligence Symbolic computation dynamic structures Precursors: IPL: 1950’s (Newell, Simon, Shaw) pseudo-code with lists; recursion added later FPL: 1956 FORTRAN with lists LISP: 1960 John McCarthy

3 LISP (cont’d) There are many dialects of LISP!
Franz Lisp, Portable Standard Lisp (PSL), LISP 1.5, Zlisp, MacLisp, Zetalisp Two recend (and important) dialects: Common Lisp: “Standardized LISP” incorporated many features of older LISP’s commercial standard (the “Ada” of LISPs) big and bulky Scheme: 1975 (still being revised) A simple, clean dialect of LISP lexically scoped (static scoping)

4 LISP (cont’d) Most of the discussion is valid for all dialects of LISP. Some will be Scheme-specific. The programming assignment will be in Scheme. Every language construct is an expression. (f arg1 arg2 .. argn) Consists of a function and some arguments (may be zero args) Constants are functions that evaluate to themselves Like “xy” or 6.

5 LISP (cont’d) Every expression returns a value!
Example: If is a function that takes three arguments: (if a b c ) => b if a is true, else c

6 LISP operations Arithmetic operations: In Scheme (or T):
(plus x y) or (+ x y ) (times x y) or (* x y ) In Scheme (or T): (add x y) or (+ x y)

7 LISP operations (cont’d)
Generalized conditional: (cond (a1 b1) (a2 b2) (an bn)) Example: (cond ((= x y) x) ((< x y) y) ((t (+ x y))) For the first ai that evaluates to true, evaluate bi and return that value. The symbol evaluating to true; in Scheme you can say else.

8 Applying functions Applying functions: (8) => 8 (+ 2 3) => 5

9 Anonymous functions Big deal: These are anonymous functions!
(lambda (x) (+ x x)) => function ((lambda (x) (+ x x)) 3 ) => 6 These are anonymous functions! How about named functions? Here Scheme is different. Big deal Param list Function body

10 Definitions Define variable expression using define
Valid at top level, i.e., not inside anything. (define x 3) (+ x 1) => 4 (define double (lambda (x) (plus x x))) (double 4) => 8

11 Definitions (cont’d) More:
(define fact (lambda (n) (if (< n 2) (* n (fact (- n 1)))))) (fact 4) => 24 (fact (fact 4)) => ”big number!”

12 Assignments Define is a declaration & initialization
set! is an assignment to a (previously declared) variable. General format: (set! variable expression) Example: (set! a (+ 4 5)) Some implementations permit set! without a define.

13 Definitions vs. assignments
What’s the difference between a define and a set!? define is used for definitions; set! is used for assignments. A set! is used to assign to a previously bound variable; a define is used to create a definition to either a bound or unbound variable; it is an error to perform a set! on an unbound variable. The result of a set! is undefined; the result of a define is the variable being bound.

14 Data types Two basic data types: 1. Atoms: numbers, symbols, strings
Predefined atoms: (), nil, t Also: 123, 'a , 'acdbc , ”acbdc” 2. Lists: '(a 10 who 6) You can also have lists of lists! '((a 1) (10 that) 6 9)

15 LISP programs LISP programs are represented as lists!!!! Why?
Program  Data are interchangeable! Lisp interpreters can easily be implemented in LISP

16 Quiz Question: How can you specify whether (f 1 2 3) is a function application or a list? Answer: By using the quote function. (quote (f A 2 3)) is a list containing the symbols f and A and the numbers 2 and 3. (quote B) returns the symbol B. As a shorthand for (quote (a b c)) use: '(a b c) (Quote e) = 'e

17 Quiz (cont’d) Question: What is the result of ... ?
(set! a 'b) (print a) Answer: b

18 Quiz (cont’d) Question: What is the result of: (set! a 'b) (print 'a)
Answer: a

19 List operations Building a list: () is the empty list (also '() )
'() = NIL '(1 2 (a b)) is the list contain 1, 2 and '(a b) (list 1 2 'a '(b c)) => '(1 2 a (b c))

20 List operations (cont’d)
Adding an element: (cons new-element list) => new-list Adding an element to a list: (cons 'a '(1 2 3)) => '(a 1 2 3) (cons 1 ()) => (1) (cons '(a b) '(c d)) => '((a b) c d) (cons '(a b) 'c)) => error The last is an error, since last argument must be a list.

21 List operations (cont’d)
cons returns a new list! Does not modify its argument ... ... but set! does (that’s what the bang indicates). (It’s an assignment.) So, (set! a '(1 2 3)) (set! b (cons 'c a)) (print b) => (c 1 2 3) (print a) => (1 2 3)

22 List operations (cont’d)
Accessing elements of a list: car: returns the first element of the list. So, (car '(a b c)) => 'a (car '((a b) c)) => '(a b) (car '()) => error

23 List operations (cont’d)
Another way of accessing elements: cdr: returns the rest of the list (everything except the first element). So, (cdr '(a b c)) => '(b c) (cdr '((a b) (c d)) => '((c d)) (cdr ()) => error

24 List operations (examples)
So, (car (cdr '(a b c))) => 'b (car (car '((a b) c d) => 'a (cdr (car (cdr (cdr '(a b (c d)))))) => (d)

25 Some shorthand Useful combinations of car and cdr have short names:
(car (cdr x)) => (cadr x) (car (cdr (cdr x))) => (caddr x) (cdr (car (cdr x))) => (cdadr x) Basic idea behind the naming convention: Take the middle letters of the access functins (car, cdr) and form a single symbol starting with “c” and ending with “r”. Not all combinations have a shorthand. Depends upon the implementation.

26 Some useful predicates
(null? L) -> returns true if L (L is a list) is ( ). (null? '(1)) => false (null? ()) => true (null? 6) => error (atom? X) -> returns true if X is an atom. (atom? 6) => true (atom? 'x) => true (atom? '(a b)) => false

27 Some useful predicates (cont’d)
(= x y) -> returns true if x and y are identical. Or you can write (eq? x y) Represents the same number or symbol or the same list. For example: (eq? 6 6) => true (eq? 'a 'b) => false In Scheme, = is used basically for numeric equality, eq? is used for everything else.

28 Some useful predicates (cont’d)
Consider this (related) sequence: (set! x '(1 2 3)) (eq? x x) => true (set! y x) (eq? x y) => true But, (eq? '(1 2 3) '(1 2 3)) => false (eq? x '(1 2 3)) => false

29 True and false Note: In LISP, true is represented by t (or #t) and false is represented by nil or ( ). (if () 6 7) => 7 (= 6 7) => will return “( )” ! So, the empty list is also the constant “false”. So, (if (cdr '(a)) 6 7) => 7 Also, anything that is not ( ) or NIL is assumed to be true! (if (car '(a b c)) 6 7) => 6

30 Sample function Sample function: Determine the length of a list:
(define length (lambda (L) (cond ((null? L) 0) (t (+ 1 (length (cdr L)))) )))

31 Sample function (cont’d)
Some shorthand is allowed: (define (length L) (if (null? L) (+ (1 length (cdr L))))) The above has an implied lambda. There are also forms of define and lambda that are like varargs in C.

32 List representation How are lists represented?
“( )” is a constant (some unique value and not a valid address). A non-empty list is represented by a cons-cell. Two components: CAR & CDR CAR CDR

33 Examples ‘(6) or 6 representation for ( ) 6 ‘(a b c) ‘a ‘b ‘c

34 Examples (cont’d) ‘(a (b c) d) a b d c

35 Examples (cont’d) (set! a ‘(1 2)) a 1 The value of a is a 2
pointer to a cons cell. 2

36 Examples (cont’d) cons creates a new cons cell. (set! a ‘(a b))
(set! b ‘(c d)) (set! c (cons a b)) c a b d ‘a ‘b c Notice that a and b are unchanged

37 Examples (cont’d) This is why eq? is a little strange!
(eq? x y) will only return true if x and y have the same value: Same number of symbols or ( ) Same address for a list.

38 List equality List equality:
(define (equal x y) (cond ((atom x) (eq x y)) ((atom y) nil )) (else (and (equal (car x) (car y)) (equal (cdr x) (cdr y)) )) Common code sequence; Base cases: take car and cdr

39 List equality (cont’d)
Remember: (set! x '(1 2 3)) (set! y x) x y The result 1 2 3

40 Copying lists What if we want a copy of a list? x y 1 1 2 2 3 3

41 Copying lists (cont’d)
To copy a list: (define (copy x) (if (atom x) x (cons (car x)) (copy (cdr x))))) To create a list from atoms) (list x y z w ... ) = (cons x (cons y ( ... ) = ”the list” (x y z w ...)

42 An exercise: Flatten Now some fun!
Let’s write a function called flatten that removes all internal parentheses (flatten '((1 2) 3 (4 5) (6 7 8) (9 10)))) ... that will yield ( ) To write this we need the function append removes one pair of parens, i.e.,: (append '(...) '(...) ) gives '( ) Or, put another way, it joins two lists together: (append '(1 2 3) '(4 5)) => ( )

43 An exercise (cont’d) Flatten:
(define (flatten lis) ((cond ((null? lis) nil) ((atom? (car lis)) (cons (car lis) (flatten (cdr lis)))) (t (append (flatten (car lis)) (flatten (cdr lis)))) )))

44 Append Append: How do you combine the elements of two lists into one list? The function append: ( append '(a b) '(c d)) => ‘(a b c d) Note that (cons ‘(a b) ‘(c d)) => ‘((a b) cd) How is append written? (define (append x y) (if (null? x) y (cons (car x) (append (cdr x) y)))) See how well recursion works with lists! Eventually null

45 Reversing a list Reverse: (Let’s reverse a list)
(define (reverse lis) (if (null? lis) nil (append (reverse (cdr lis) (list (car lis)) ))) list: creates a list out of a set of elements.

46 Reversing a list (cont’d)
Examples: (reverse '( (1 2) (3 4) 5) ) => (append (reverse ‘((3 4) 5) (lis ‘(1 2))) => (append '(5 (3 4)) ((1 2))) => (5 (3 4) (1 2)))

47 Reversing a list (cont’d)
But this is quadratic complexity! To reverse a size n list, call append on sizes 1, ... , n Complexity = n = n2 (approximately) So, “kiss off” LISP ... ... since basic list operations (that is, the LISP stuff) take n2 in LISP and n in Pascal. But wait ...

48 Reversing a list (cont’d)
Consider: (define (reverse lis) (reverse1 lis nil)) (define (reverse1 f r) (if (null? f) r (reverse1 (cdr f) (cons (car f) r)) )))

49 Reversing a list (cont’d)
Example: reverse '( (1 2) (3 4) 5)) => reverse1 '( (1 2) (3 4) 5) nil) => reverse1 '( (3 4) 5) '((1 2))) => reverse1 '(5) '((3 4) (1 2))) => reverse1 nil '(5 (3 4) (1 2)))

50 Side effects Lists can be modified! Side effects! Example:
(set-car! L A) == (set (car L) A) (set-cdr! L M) == (set (cdr L) M) Not official Scheme

51 Side effects (cont’d) Example: (set! x '((a b) c d)) x a c b d

52 Side effects (cont’d) Example: Called replaca in old LISP.
(set-car! x '(1 2)) Called replaca in old LISP. x a 1 ‘c b 2 ‘d

53 Side effects (cont’d) Example: (set! x '(1 2 3)) (set-cdr! x '(4 5)) x

54 Side effects (cont’d) Examples: x is modified. (set! x '(1 2 3))
(print x) => '(1 2 3) (set! y x) (print y) => '(1 2 3) (set-car! y ‘8) (print x) => '(8 2 3) (eq? x y) => #t x is modified.

55 Quiz Question: What happens here? Answer: a a a a a a a a a a a...
(set! x '(a b c)) (set-cdr! x x) (print x) Answer: a a a a a a a a a a a...

56 Quiz (cont’d) Question: Why? Answer: x a b c

57 Associative Lists Assume you have a list of pairs:
L = ((a b) (x y) ... (q z)) Better L = ( (f1 s1) (f2 s2) ... (fn sn) ) The associative list is a concept that appears in many programing languages (LISP, SETL, Perl, etc.) (assoc x L) = first pair where car is x (assoc 5 ((8 2) (5 4 4) (9 1) (5 1))) yields (5 4 4)

58 Associative lists (cont’d)
Example: (define grades '((joe 10) (bob 2) (alice 9) (sarah 6) (ted nil) )) (assoc sarah grades) => (sarah 6) (cadr (assoc sarah grades)) => 6 (assoc tom grades) => #f

59 Recursion Recursion is the primary mechanism for repeating actions.
Control structures: if, cond, function call seen already (or x y) (cond (x t) (t y)) (and x y) (cond (x y) (t nil)) returns value of first true expression returns value of first false expression

60 Scheme Loop Scheme loop. Not in all LISPs.
(do ((var1 init1 step1) ((vark initk stepk) (test expression) commands) Done if test is false, i.e., body Value of do

61 Scheme Loop (cont’d) Example: Empty body in loop. Value is 60.
(do ((x '( ) (cdr x)) (total 0 (+ total (car x))) ((null? x) total) ) Empty body in loop. Value is 60.

62 Input/output Frequent in old LISP programs. Less frequent now.
set-car!, set! I/O is an important side effect. (read): gets one object. (write obj): machine readable (display obj): human readable (read-char), (eof-object?), (newline)

63 Input/output (examples)
Some examples: ==> (define v (read)) 123<cr> ==> v 123

64 Multiple actions Multiple actions: An old friend.
(lambda (x y) (+ x y)) An old friend. (lambda (x y) (+ x y) (display x) (display y) ) Also, body of DO loop and others (see the Scheme report)

65 More on recursion Using recursion, it is easy to perform an operation on each element of a list. (instead of using vectors) (define (addl_map a) (cond ((null a) nil) (t (cons (+ 1 (car a)) (addl_map (cdr a)))) )) Adds 1 to each element of a list (assumes a flat list of numbers). Question: What is the value returned by (addl_map a)?

66 Function parameters Do I have to write a different function for each operation I want to perform on the elements of a list? No. Pass the operation (function) as a parameter! Applies the map (that is, function) f to each car (that is, item) of x. (define (mapcar f x) (cond ((null? x) nil) (t (cons (f (car x)) (mapcar f (cdr x))) )) Application of function f. Applies f to every element of the list X.

67 Function parameters (cont’d)
So, (mapcar add1 '( )) => ( ) where (define (add1 x) (+ x 1)) (mapcar times2 '(3 4 5)) => (6 8 10)

68 Higher order functions
Passing functions as parameters leads to the notion of higher order functions. Also known as functionals. They are: functions that take other functions as parameters and/or return functions. We saw that mapcar takes a function as a parameter. How about returning a function as the result of an expression???

69 Higher order functions (cont’d)
Suppose: (add1 x) adds 1 to x (sub1 x) subtracts 1 from x Then: (define (foo x) (cond ((= x 1) add1) (t sub1)))) takes a parameter x; if x=1 then return the function add1; otherwise return the fuction sub1.

70 Higher order functions (cont’d)
Examples: (foo 1) => ”function add1” (foo 2) => ”function sub1” ((foo 2) 6) => 7 ((foo 2 18) => 17 (mapcar (foo3) '(4 5 6) => '(3 4 5)

71 Higher order functions and lambda
What if you wanted to add 3 to every element of a list? Well, you could do: (define (add3 x) (+ x 3)) mapcar add3 '(...)) However, if you are only doing itonce you probably don’t want to bother defining a new function “add3”. Instead, write an expression that behaves like the function add6.

72 Another use for lambda A lambda expression is a “nameless” function.
(lambda (x) (+ x 3)) This returns a function which takes a parameter x and adds 3 to it. (mapcar (lambda (x) (+ x 3)) '(1 2 3)) => (4 5 6) ((lambda (y) (* y z)) 6) => 12


Download ppt "Programming Languages I LISP"

Similar presentations


Ads by Google