.comment -*- Mode:TEXT; -*- .comment talks about dotted pairs and points to the functions .comment EXAMINE-LIST and DISPLAY-LIST .document DOT - A description of the dotted pair formalism for Lisp lists. .tag DOT Lesson DOT, Version 2 Kent M. Pitman, 5/25/79 revised by Victoria Pigman, 9/3/82 This lesson deals with a special notation for describing list structure called the dotted-pair. As discussed in Lesson INTRO, the Lisp function CONS is used for putting two objects together. In essence, you may think of CONS as saying that you want to create a new something which is composed of two pieces (the arguments to CONS). Let's take an example: (CONS 'A 'B) will make a new object that has a CAR which is the atom A and a CDR which is the atom B. We can represent this object conceptually (Note: we are not talking about how to talk to Lisp now - but formalizing a conceptual notation) by saying the object is a pair of the form (A . B) where A is the left half and B is the right half. Similarly, the result of: (CONS '(A B) '(C D)) might be represented in our conceptual scheme by the notation: ((A B) . (C D)) A more cumbersome (but visually helpful) notation which you may see on occasion for the same concept would be: --------- | . | . | -/-----\- / \ (A B) (C D) In other words, CONS creates an object with two arms extending from it. One arm points to the CAR, or (A B) in this case. The other arm points to the CDR, which is (C D) in this case. A common version of this notation that takes up more room, but is sometimes quite helpful, breaks down each piece of the CONS into its constituent CONS's and keeps going until it gets down to having just individual symbols in each box. This notation gets the "tree structure" of your list for you, a name that makes sense if you look at it for a bit. Here's the same CONS as above displayed in this more long-winded fashion. --------- | | | | . | . | | | | -/-----\- / \ --------- --------- | | | | | | | A | . | | C | . | | | | | | | ------|-- ------|-- | | --------- --------- | | | | | | | B | / | | D | / | | | | | | | --------- --------- (/ is used to indicate a NIL atome goes in that box.) .pause Let us now conceptualize how we could create a structure which acts like a list using our dotted pair notation. We will have to build it out of pieces that have exactly two pieces. How can we do this? To start with, let's take the empty list, NIL... If we want to add an element, FOO, to it, we could do this by saying (CONS 'FOO NIL). This will return us an object of the form (FOO . NIL) But now we have a problem. There is no more space in the CONS for another element to be added. So to add a new element, BAR, we might make a new dotted pair whose first element is BAR and whose second element is the pair (FOO . NIL). Thus we say (CONS 'BAR (CONS 'FOO NIL)) which returns a form like this: (BAR . (FOO . NIL)) To add yet another element to the list, we do the same sort of thing. (CONS 'BAZ (CONS 'BAR (CONS 'FOO NIL))) will produce (BAZ . (BAR . (FOO . NIL))) These dots are getting annoying! Let's create a shorthand notation. Suppose that every time you see a "." you look at the next thing after it. If the next thing is an atom, print the "." and then the atom. But if it's also a pair, don't print the "." and leave off the extra parentheses around the next pair. For example: (BAZ . BAR) => (BAZ . BAR) ; It was an atom. (BAZ . (BAR . GUNK)) => (BAZ BAR . GUNK) ; This is a bit nicer! (A . (B . (C . D))) => (A B C . D) ; This is a lot nicer! .pause In the case of NIL, we do a special trick. If NIL is the last atom in a list, just forget about printing the " . NIL" at the end of a list completely. So, (A . NIL) => (A) (A . (B . (C . NIL))) => (A B C) Study these shorthand rules -- they will be used often. In fact,the Lisp printer does just that when printing out a list. In a minute, you'll get a chance to type in a few lists using this dotted pair notation. When you try, remember the following rules: [1] Make sure you quote the lists if you don't want them to be evaluated! just saying (A . B) to Lisp will cause Lisp to try to call a function A! Be sure to say '(A . B) so that it knows you just want back literally what you type in. [2] Make sure that you put exactly one thing to the right and left of a dot. For instance... '(A . B . C) is NOT allowed. Dotted pairs have exactly two halves. No fair forcing 3 things in! HOWEVER, '(A B . C) IS allowed because it is really a contraction for '(A . (B . C)) which is a legal form. If you get a ";DOT CONTEXT ERROR" message from Lisp it means you botched up by having a "." without exactly 1 thing on either side of it. Give some of these examples a try. Note how Lisp abbreviates the printout. '(A . NIL) '(A . (B . (C . NIL))) '((A . NIL) . (B . NIL)) .try Note that you can also mix notations. For example, if you know taht (A . (B . (C . NIL))) will contract to just (A B C) then it should be clear that '(D . (A B C)) will contract to (D A B C). Give these examples a try: '(A . (C D E . (D . NIL))) '((A B C) . (D E F)) .try Make sure you understand how Lisp abbreviates dotted pairs when it types out lists. It makes things much simpler when you start playing with CAR and CDR. If you ever get stuck understanding what CAR and CDR are going to return, you can always draw out the dotted pair notation for a list and see what's on the right or left side of the outermost pair. Now as a last exercise, try doing it the other way around. Given a list like (A B (C D E) (F G)) can you construct it using CONS? Try the function EXAMINE-LIST which we have provided for you to view the internal structure of a list. If you type (EXAMINE-LIST) it will either offer to re-examine the last argument you gave to it or to read a new list from the console and then describe its structure to you. If you do (EXAMINE-LIST ) it will describe the list-structure of the value of . The function DISPLAY-LIST has the same convention about what arguments it takes, but just shows you the tree structure of your list and not the other stuff that EXAMINE-LIST does. .try .next SETQ