# Lisp Internals. 2 A problem with lists In Lisp, a list may “contain” another list –For example, (A (B C)) contains (B C) So, how much storage do we need.

## Presentation on theme: "Lisp Internals. 2 A problem with lists In Lisp, a list may “contain” another list –For example, (A (B C)) contains (B C) So, how much storage do we need."— Presentation transcript:

Lisp Internals

2 A problem with lists In Lisp, a list may “contain” another list –For example, (A (B C)) contains (B C) So, how much storage do we need to allocate for a list? –If any list can contain any other list, there is no limit to the size of storage block we may need –This is impractical; we need another solution

3 Pointers Instead of actually putting one list inside another, we put a pointer to one list inside another –A pointer is a fixed, known size This partially solves the problem, but... –A list can contain any number of elements –For example, the list ((A)(B)(A)(C)) contains four lists –This still leaves us needing arbitrarily large blocks of storage

4 CAR and CDR We can describe any list as the sum of two parts: its “head” (CAR) and its “tail” (CDR) –The head is the first thing in the list –The head could itself be an arbitrary list –The tail of a list is another (but shorter) list Thus, any list can be described with just two pointers This provides a complete solution to our problem of arbitrarily large storage blocks

5 S-expressions In Lisp, everything is an S-expression An S-expression is an atom or a list You can think of these as using two different kinds of storage locations--one kind for atoms, another kind for the parts of a list –This is an oversimplification, but it will do for now

6 Atoms An atom is a simple thing, and we draw it in a simple way: Sometimes we don’t bother with the boxes: HELLO ABCNIL HELLO ABCNIL

7 Lists A list has two parts: a CAR and a CDR We draw this as a box, called a cons cell, with two compartments, called the car field and the cdr field In each of these compartments we put an arrow pointing to its respective value: car fieldcdr fieldcar field value of carvalue of cdr

8 Example I ( A ) A NIL A

9 Example II ( A B C ) A(B C)B(C)CNIL ABC

10 Example III BA NIL ((A) B)

11 Example IV B A NIL C D ((A B) (C D))

12 Dotted pairs In a simple list, every right-pointing arrow points to a cons cell or to NIL If a right-pointing arrow points to an atom, we have a dotted pair (A. B) A B

13 Lisp lists are implemented with dotted pairs Therefore, (A) = (A. NIL) All structures in Lisp can be created from atoms and dotted pairs ( A ) = A NIL = (A. NIL)

14 Example V A B C D ((A. B). (C. D))

15 Writing dotted pairs A dotted pair is written (and printed) using parentheses and a dot: (A. B) If the CDR of a dotted pair is NIL, the dot and the NIL are omitted: (A. NIL) = (A) If the CDR is another cons cell, Lisp doesn’t print the dot or the parentheses –(A. (B. (C. NIL))) = (A B C) –(A. (B. (C. D))) = (A B C. D)

16 Efficiency of CDR Suppose L is the list (A B C D E) Then (CDR L) is the list (B C D E) Isn’t it expensive to create this new list? Answer: NO! It’s incredibly cheap! Lisp just copies a pointer: A(B C D E) L (CDR L)

17 Efficiency of CAR and CONS CAR is just like CDR ; you just copy a pointer CONS takes more work; you have to allocate and fill one cons cell A Here’s the atom A B NIL Here’s the list (B) Here’s the cons cell we add to create the list (A B)

18 Sharing structure List L and list (CDR L) are said to share structure But if L = (A B C D E) and M = (CDR L), then when you change L, won’t M be changed? Yes, but... –this is where the real genius of Lisp comes in... You never change L ! None of the basic functions ever change anything that’s already there Only CONS adds anything The result is an extraordinarily efficient language!

19 Memory If you only add structure, and never change or delete anything, won’t you run out of memory? Lisp uses garbage collection to recover structures that you are no longer using –More convenient for the programmer –Safer (less subject to human error) –Extremely effective in general

20 Java isn’t Lisp Although Lisp’s way of handling lists is elegant and efficient, it’s not the only way –Modifying the middle or end of a list is expensive There are many ways we might implement lists in Java Lisp’s implementation of lists is a great example, but not necessarily the final word

21 A possible Java implementation class Cell { } class Atom extends Cell { String value; Atom(String value) { // constructor this.value = value; } } class ConsCell extends Cell { Cell car; Cell cdr; ConsCell(Cell car, Cell cdr) { // constructor this.car = car; this.cdr = cdr; } }

22 Another possible implementation class Cell { boolean isAtom; String value; Cell car, cdr; Cell(String value) { // constructor isAtom = true; this.value = value; } Cell(Cell car, Cell cdr) { // constructor isAtom = false; this.car = car; this.cdr = cdr; } }

23 Implementing the functions I class Lisp { static Cell car(Cell c) { return c.car; } static Cell cdr(Cell c) { return c.cdr; } static Cell cons(Cell c1, Cell c2) { return new Cell(c1, c2); }

24 Implementing the functions II static boolean atom(Cell c) { return c.isAtom; } static boolean eq(Cell c1, Cell c2) { return c1.value.equals(c2.value); } }

25 The End

Download ppt "Lisp Internals. 2 A problem with lists In Lisp, a list may “contain” another list –For example, (A (B C)) contains (B C) So, how much storage do we need."

Similar presentations