mirror of
https://github.com/PDP-10/its.git
synced 2026-03-23 17:22:35 +00:00
192 lines
6.6 KiB
Plaintext
Executable File
192 lines
6.6 KiB
Plaintext
Executable File
.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 <variable-name>)
|
|
|
|
it will describe the list-structure of the value of <variable-name>.
|
|
|
|
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
|