1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s...

24
1 Lists in Lists in Lisp and Lisp and Scheme Scheme

Transcript of 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s...

Page 1: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

1

Lists in Lists in Lisp and Lisp and SchemeScheme

Page 2: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

2

Lists in Lisp and SchemeLists in Lisp and Scheme Lists are Lisp’s fundamental data structures.Lists are Lisp’s fundamental data structures. However, it is not the only data structure.However, it is not the only data structure.

There are arrays, characters, strings, etc.There are arrays, characters, strings, etc. Common Lisp has moved on from being Common Lisp has moved on from being

merely a LISt Processor.merely a LISt Processor. However, to understand Lisp and Scheme However, to understand Lisp and Scheme

you must understand listsyou must understand lists common functions on themcommon functions on them how to build other useful data structures how to build other useful data structures

using them.using them.

Page 3: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

3

In the beginningIn the beginningwas the cons (or pair)was the cons (or pair) What cons really does is combinesWhat cons really does is combines

two objects into a two-part objecttwo objects into a two-part objectcalled a called a cons cons in Lisp and a pair in Schemein Lisp and a pair in Scheme

Conceptually, a cons is a pair of pointers -- Conceptually, a cons is a pair of pointers -- the first is the car, and the second is the cdr.the first is the car, and the second is the cdr.

Conses provide a convenient representation Conses provide a convenient representation for pairs of any type.for pairs of any type.

The two halves of a cons can point to any The two halves of a cons can point to any kind of object, including conses.kind of object, including conses.

This is the mechanism for building lists.This is the mechanism for building lists. (pair? ‘(1 2) ) => T(pair? ‘(1 2) ) => T

nil

a

Page 4: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

4

PairsPairs

Lists in CL and Scheme are defined as Lists in CL and Scheme are defined as pairs.pairs.

Any non empty list can be considered Any non empty list can be considered as a pair of the first element and the as a pair of the first element and the rest of the list.rest of the list.

We use one half of the cons to point We use one half of the cons to point to the first element of the list, and the to the first element of the list, and the other to point to the rest of the list other to point to the rest of the list (which is either another cons or nil).(which is either another cons or nil).

nil

a

Page 5: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

5

Box notationBox notation

nil

a

A one element list (A)

nil

a b c

A list of 3 elements (A B C)

Where NIL = ‘( )

Page 6: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

6

What sort of list is this?What sort of list is this?

nil

a d

b c

> (set! z (list ‘a (list ‘b ‘c) ‘d))(A (B C) D)

(car (cdr z))??

Z

Page 7: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

7

Pair?Pair?

The function pair?The function pair? returns true if its returns true if its argument is a cons (pair? = consp in CL)argument is a cons (pair? = consp in CL)

So list? could be defined:So list? could be defined:

(defun myListp (x) (or (null x) (consp x)))(defun myListp (x) (or (null x) (consp x))) Since everything that is not a pair is an Since everything that is not a pair is an

atom, the predicate atom, the predicate atomatom could be defined: could be defined:

(defun myAtom (x) (not (pair? x)))(defun myAtom (x) (not (pair? x))) Remember, Remember, nilnil is both an is both an atomatom and a and a list list..

Page 8: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

8

EqualityEquality Each time you call cons, Scheme allocates a Each time you call cons, Scheme allocates a

new piece of memory with room for 2 pointers. new piece of memory with room for 2 pointers. So if we call cons twice with the same So if we call cons twice with the same

arguments, we get back two values that look arguments, we get back two values that look the same, but are in fact distinct objects:the same, but are in fact distinct objects:> (define l1 (cons 'a ‘()))> (define l1 (cons 'a ‘()))(A)(A) (define l2 (cons 'a nil)))(define l2 (cons 'a nil))) (A)(A) (eq? l1 l2)(eq? l1 l2) #f#f (equal l1 l2)(equal l1 l2) #t#t (and (eq? (car l1)(car l2)) (eq? (cdr l1)(cdr l2)))(and (eq? (car l1)(car l2)) (eq? (cdr l1)(cdr l2))) #t#t

Page 9: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

9

Equal?Equal? We also need to be able to ask whether two We also need to be able to ask whether two

lists have the same elements.lists have the same elements. CL provides an equality predicate for this, CL provides an equality predicate for this,

equalequal.. Eq? returns true only if its arguments are the Eq? returns true only if its arguments are the

same object, andsame object, and equal, more or less, returns true if its equal, more or less, returns true if its

arguments would print the same.arguments would print the same.> (equal? l1 l2)> (equal? l1 l2)

TT

Note: if x and y are eq?, they are also equal?Note: if x and y are eq?, they are also equal?

Page 10: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

10

Equal?Equal?

(define (equal? x y)(define (equal? x y)

; this is ~ how equal? could be ; this is ~ how equal? could be defineddefined

(cond ((number? x) (= x y))(cond ((number? x) (= x y))

((not (pair? x)) (eq? x y))((not (pair? x)) (eq? x y))

((not (pair? y)) nil)((not (pair? y)) nil)

((equal (car x) (car y))((equal (car x) (car y))

(equal (cdr x) (cdr y)))))(equal (cdr x) (cdr y)))))

Page 11: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

11

Does Lisp have pointers?Does Lisp have pointers?

One of the secrets to understanding Lisp is to realize One of the secrets to understanding Lisp is to realize that variables have values in the same way that lists that variables have values in the same way that lists have elements.have elements.

As conses have pointers to their elements, As conses have pointers to their elements, variables have pointers to their values.variables have pointers to their values.

What happens, for example, when we set two What happens, for example, when we set two variables to the same list:variables to the same list:> (set! x ‘(a b c))> (set! x ‘(a b c))(A B C)(A B C)> (set! y x)> (set! y x)(A B C)(A B C) This is just like

in JavaThis is just likein Java

Page 12: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

12

The location in memory associated The location in memory associated with the variable x does not contain with the variable x does not contain the list itself, but a pointer to it.the list itself, but a pointer to it.

When we assign the same value to y, When we assign the same value to y, Sccheme copies the pointer, not the Sccheme copies the pointer, not the list.list.

Therefore, what would the value ofTherefore, what would the value of

> (eq? x y)> (eq? x y)

be, #t or #f?be, #t or #f?

Does Scheme have Does Scheme have pointers?pointers?

Page 13: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

13

Building ListsBuilding Lists The function The function copy-listcopy-list takes a list and takes a list and

returns a copy of it.returns a copy of it. The new list will have the same The new list will have the same

elements, but contained in new conses.elements, but contained in new conses.> (set! x ‘(a b c))> (set! x ‘(a b c))

(A B C)(A B C)

> (set! y (copy-list x))> (set! y (copy-list x))

(A B C)(A B C) Spend a few minutes to draw a box Spend a few minutes to draw a box

diagram of x and y to show where the diagram of x and y to show where the pointers point.pointers point.

Page 14: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

14

LISP’s Copy-listLISP’s Copy-list

Copy-list is a built in function but could be Copy-list is a built in function but could be defined as followsdefined as follows

(define (copy-list s)(define (copy-list s)

(if (not (pair? s))(if (not (pair? s))

ss

(cons (copy-list (car s))(cons (copy-list (car s))

(copy-list (cdr s)))))(copy-list (cdr s)))))

There is also a copy-tree that makes a copy There is also a copy-tree that makes a copy of the entire s-expression.of the entire s-expression.

Page 15: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

15

AppendAppend

TheScheme/Lisp function TheScheme/Lisp function appendappend returns returns the concatenation of any number of lists:the concatenation of any number of lists:

> (append ‘(a b) ‘(c d) ‘(e))> (append ‘(a b) ‘(c d) ‘(e))(A B C D E)(A B C D E)

AppendAppend copies all the arguments except copies all the arguments except the last.the last. If it didn’t copy all but the last argument, If it didn’t copy all but the last argument,

then it would have to modify the lists then it would have to modify the lists passed as arguments. Such side effects passed as arguments. Such side effects are very undesirable, especially in are very undesirable, especially in functional languages.functional languages.

Page 16: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

16

appenappendd

The two argument version of append could The two argument version of append could have been defined like this.have been defined like this.

(define (append2 s1 s2)(define (append2 s1 s2) (if (null? s1) (if (null? s1) s2 s2 (cons (car s1) (cons (car s1)

(append2 (cdr s1) s2))))(append2 (cdr s1) s2)))) Notice how it ends up copying the top level Notice how it ends up copying the top level

list structure of it’s first argument.list structure of it’s first argument.

Page 17: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

17

List access functionsList access functionsTo find the element at a given position To find the element at a given position in a list use the function list-ref (in a list use the function list-ref (nth in nth in CL)CL)..

> (list-ref ‘(a b c) 0)> (list-ref ‘(a b c) 0)

AAand to find the and to find the nnth cdr, use list-tail th cdr, use list-tail ((nthcdr in CL)nthcdr in CL)..

> (list-tail ‘(a b c) 2)> (list-tail ‘(a b c) 2)

(C)(C)Both functions are zero indexed.Both functions are zero indexed.

Page 18: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

18

Lisp’s nth and nthcdrLisp’s nth and nthcdr(define (nth (n l)(define (nth (n l) (cond ((null? l) nil)(cond ((null? l) nil) ((= n 0) (car l))((= n 0) (car l)) (#t (nth (- n 1) (cdr l)))))(#t (nth (- n 1) (cdr l)))))

(define (nthcdr n l)(define (nthcdr n l) (cond ((null? l) nil)(cond ((null? l) nil) ((= n 0) (cdr l))((= n 0) (cdr l)) (#t (nthcdr (- n 1) (cdr l)))))(#t (nthcdr (- n 1) (cdr l)))))

Page 19: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

19

Accessing listsAccessing lists The function The function lastlast returns the last element in a list returns the last element in a list

(define (last l) (define (last l)

(if (null? (cdr l))(if (null? (cdr l))

(car l)(car l)

(last (cdr l))))(last (cdr l))))

> (last ‘(a b c))> (last ‘(a b c))

(C)(C) Note: in CL, last returns the last cons cellNote: in CL, last returns the last cons cell We also have: We also have: firstfirst, , second, thirdsecond, third, and , and CxRCxR, ,

where where xx is a string of up to four is a string of up to four aas or s or dds.s. E.g., cadr, caddr, cddr, cdadr, …E.g., cadr, caddr, cddr, cdadr, …

Page 20: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

20

MemberMember Member Member returns true, but instead of returns true, but instead of

simply returning simply returning tt, its returns the part of , its returns the part of the list beginning with the object it was the list beginning with the object it was looking for.looking for.

> (member ‘b ‘(a b c))> (member ‘b ‘(a b c))

(B C)(B C) membermember compares objects using compares objects using equal?equal? There are versions that use eq? and There are versions that use eq? and

eqv? And that take an arbitrary functioneqv? And that take an arbitrary function

Page 21: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

21

MemfMemf If we want to find an element satisfying If we want to find an element satisfying

an arbitrary predicate we use the an arbitrary predicate we use the function function memfmemf::> (memf odd? ‘(2 3 4))> (memf odd? ‘(2 3 4))(3 4)(3 4)

Which could be defined like:Which could be defined like:(define (memf f l)(define (memf f l) (cond ((null? l) #f)(cond ((null? l) #f) ((f (car l)) l)((f (car l)) l) (#t (memf f (cdr l)))))(#t (memf f (cdr l)))))

Page 22: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

22

Dotted ListsDotted Lists The kind of lists that can be built by calling The kind of lists that can be built by calling listlist

are more precisely known as are more precisely known as proper listsproper lists..A proper list is either A proper list is either the empty listthe empty list, or a , or a conscons

whose whose cdrcdr is a proper list. is a proper list. However, conses are not just for building lists However, conses are not just for building lists

-- whenever you need a structure with two -- whenever you need a structure with two fields you can use a cons.fields you can use a cons.

You will be able to use You will be able to use carcar to refer to the first to refer to the first field and field and cdrcdr to refer to the second. to refer to the second.> (set! pair (cons ‘a ‘b))> (set! pair (cons ‘a ‘b))

(A . B)(A . B) Because this cons is not a proper list, it is Because this cons is not a proper list, it is

displayed in displayed in dot notationdot notation..In dot notation the car and cdr of each cons In dot notation the car and cdr of each cons

are shown separated by a period.are shown separated by a period.

Page 23: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

23

A pair that isn’t a proper list is A pair that isn’t a proper list is called a dotted pair.called a dotted pair.

However, remember that a dotted However, remember that a dotted pair isn’t really a list at all.pair isn’t really a list at all.

It is a just a two part data structure.It is a just a two part data structure.

a b

(A . B)

Page 24: 1 Lists in Lisp and Scheme. 2 Lists are Lisp’s fundamental data structures. Lists are Lisp’s fundamental data structures. However, it is not the only.

24