518 lines
15 KiB
Plaintext
518 lines
15 KiB
Plaintext
File: MULISP3.LES (c) 12/27/85 Soft Warehouse, Inc.
|
||
|
||
CLRSCRN
|
||
This is muLISP lesson #3. Estimated completion time is 50 minutes.
|
||
|
||
The first two lessons taught the fundamentals of muLISP programming using
|
||
pure muLISP. Everything you learned about pure muLISP is of course true
|
||
of full muLISP; however, there is much that was left unsaid. With this
|
||
lesson we shall commence describing the full capabilities of muLISP.
|
||
|
||
In Lesson #3 we will examine each of the three primitive muLISP data objects
|
||
in detail. This lesson is primarily informative in nature and does not
|
||
provide a lot in the way of interesting problems for you to solve. However,
|
||
it does provide an essential foundation for the later lessons.
|
||
|
||
|
||
CONTINUE
|
||
There are three types of primitive data objects in muLISP: Symbols, Numbers,
|
||
and Conses.
|
||
|
||
muLISP provides numerous functions for recognizing, comparing, combining, and
|
||
operating on these primitive data objects. This allows you to construct
|
||
complex data structures that can accurately model in the computer virtually
|
||
any real world problem. Therefore, we begin our discussion of muLISP with a
|
||
description of the three basic data objects.
|
||
|
||
As you may recall, pure muLISP has only two types of data objects: Atoms and
|
||
Lists. In full muLISP, atoms are further subdivided into Symbols and Numbers.
|
||
In full muLISP, lists are only a subset of the more general structures called
|
||
binary trees made up of Conses.
|
||
|
||
|
||
CONTINUE
|
||
The first type of data object we shall discuss is the symbol. Associated with
|
||
each muLISP symbol are 4 attributes:
|
||
|
||
1. Print name string: A unique string of ASCII characters used by the system
|
||
to identify the symbol on input and to display the symbol on output. A
|
||
symbol's print name string cannot be changed.
|
||
|
||
2. Current value: A symbol's value can be any muLISP data object, including
|
||
itself. The default value of a symbol is the symbol itself.
|
||
|
||
3. Property list: The property list contains the symbol's property values
|
||
indexed on property keys. See the muLISP lesson on property values for
|
||
more information about using properties. The default property list of a
|
||
symbol is the null list.
|
||
|
||
4. Function definition: A symbol's function definition is applied to the
|
||
arguments given when the symbol is called as a function. The default
|
||
function definition invokes the "Undefined Function" error break.
|
||
|
||
|
||
CONTINUE
|
||
The recognizer function SYMBOLP returns T if its single argument is a symbol;
|
||
otherwise it returns NIL. For example:
|
||
|
||
$ (SYMBOLP 'XYZ)
|
||
|
||
$ (SYMBOLP 41)
|
||
|
||
$ (SYMBOLP '(DOG CAT COW))
|
||
|
||
During this break, see whether the null list, (), is a symbol or not. To
|
||
return to the lesson, type (RETURN) and press the <RETURN> key.
|
||
|
||
BREAK
|
||
CLRSCRN
|
||
As discussed in an earlier lesson, the comparator function EQL is used to
|
||
determine if two symbols are the same. For example:
|
||
|
||
$ (EQL 'APPLE (CAR '(APPLE ORANGE LEMON)))
|
||
|
||
|
||
CONTINUE
|
||
Since blank spaces, parentheses, and some other special characters have
|
||
special significance to the muLISP, a quoted string must be used to create a
|
||
symbol with such characters in its print name string. Simply enclose the
|
||
string containing such characters within double quotes to create such a
|
||
symbol. For example:
|
||
|
||
$ "This is a (single) symbol!"
|
||
|
||
Normally the double quotes around symbols containing special characters are
|
||
NOT displayed when the symbol is output. (Note: Double quote marks are
|
||
automatically displayed around such symbols if the value of the control
|
||
variable PRIN1 is NIL.)
|
||
|
||
The empty string, entered as "", is also a symbol. For example:
|
||
|
||
$ (SYMBOLP "")
|
||
|
||
CONTINUE
|
||
The double quote mark itself can be included in a print name string by
|
||
entering a backslash and a quote mark for each desired quote mark in the
|
||
string. For example:
|
||
|
||
$ "She said, \"I am learning muLISP.\""
|
||
|
||
When entering symbols using double quote marks, it is essential to balance the
|
||
quote marks. After entering a quote mark, muLISP will continue to think you
|
||
are entering a single symbol until a matching quote mark is read.
|
||
|
||
During this break, see what happens when you enter a symbol with an unmatched
|
||
double quote mark and press the <RETURN> key. To return to the lesson, you
|
||
will need to balance the quote marks so you will get the dollar sign prompt.
|
||
|
||
BREAK
|
||
CLRSCRN
|
||
A symbol can be assigned a value. The value can be any muLISP data object
|
||
including itself. The default value of most muLISP symbols is the symbol
|
||
itself.
|
||
|
||
SET is the primitive function used to set the value of a symbol (SET's first
|
||
argument) to a value (SET's second argument). Of secondary importance is the
|
||
fact that SET returns its second argument as its value. For example:
|
||
|
||
$ (SET 'FRUITS '(APPLES ORANGES LEMONS PEARS))
|
||
|
||
$ FRUITS
|
||
|
||
During this break, SET the symbol VOWELS to a list of the 5 vowels in the
|
||
alphabet.
|
||
|
||
BREAK
|
||
CLRSCRN
|
||
Generally the first argument to SET will be a quoted symbol. Rather than
|
||
having to explicitly quote the symbol, the function SETQ (SET Quote) can be
|
||
used instead. SETQ automatically quotes its first argument but NOT its
|
||
second. For example, rather than using SET to assign a list to 'VOWELS, you
|
||
could use SETQ as follows:
|
||
|
||
$ (SETQ VOWELS '(A E I O U))
|
||
|
||
During this break, use SETQ to add the letter Y to VOWELS by CONSing it onto
|
||
the current value of VOWELS.
|
||
|
||
BREAK
|
||
The following adds Y to the list of vowels:
|
||
|
||
$ (SETQ VOWELS (CONS 'Y VOWELS))
|
||
|
||
|
||
CONTINUE
|
||
The second type of muLISP data object we shall discuss are Numbers. Numbers
|
||
are further subdivided into integers and ratios. Integers are entered as a
|
||
contiguous series of digits, optionally preceded by a minus sign.
|
||
|
||
Since the value of a number is the number itself, there is no need to quote
|
||
numbers:
|
||
|
||
$ 41
|
||
|
||
$ -75
|
||
|
||
The comparator function EQL is used to test for the equality of two numbers:
|
||
|
||
$ (EQL 3 4)
|
||
|
||
$ (EQL 0 -0)
|
||
|
||
|
||
CONTINUE
|
||
Ratios can be entered using either decimal or slash notation (i.e. as two
|
||
series of digits separated by a decimal point or a slash character, optionally
|
||
preceded by a minus sign). By default, ratios are displayed using decimal
|
||
notation:
|
||
|
||
$ 3/4
|
||
|
||
$ -0.34
|
||
|
||
$ (EQL 0.4 2/5)
|
||
|
||
|
||
CONTINUE
|
||
If the control variable *POINT* is NIL, muLISP displays ratios using slash
|
||
notation instead of decimal notation. Note that ratios are automatically
|
||
reduced to lowest terms. Also ratios having a denominator of one are
|
||
automatically converted to integers.
|
||
|
||
$ (SETQ *POINT* NIL)
|
||
|
||
$ -5/7
|
||
|
||
$ 0.33333333
|
||
|
||
$ 12/9
|
||
|
||
$ 5/1
|
||
|
||
|
||
CONTINUE
|
||
If the control variable *POINT* is zero or a positive integer, muLISP
|
||
displays ratios using decimal notation to a maximum of POINT digits:
|
||
|
||
$ (SETQ *POINT* 3)
|
||
|
||
$ 2/3
|
||
|
||
$ (SETQ *POINT* 7)
|
||
|
||
$ 2/3
|
||
|
||
|
||
CONTINUE
|
||
The primitive recognizer function INTEGERP returns T if its argument is an
|
||
integer; otherwise it returns NIL. For example:
|
||
|
||
$ (INTEGERP 100)
|
||
|
||
$ (INTEGERP 'FIVE)
|
||
|
||
$ (SETQ PRIMES '(2 3 5 7 11))
|
||
|
||
$ (INTEGERP (CAR PRIMES))
|
||
|
||
|
||
CONTINUE
|
||
The primitive recognizer function NUMBERP returns T if its argument is a
|
||
number (i.e. either an integer or ratio); otherwise it returns NIL. For
|
||
example:
|
||
|
||
$ (NUMBERP 100)
|
||
|
||
$ (NUMBERP 457.23)
|
||
|
||
$ (NUMBERP -23/7)
|
||
|
||
|
||
During this break, use NUMBERP and SYMBOLP to see if a sequence of digits
|
||
enclosed in double quotes (e.g. "137") is a number or a symbol.
|
||
|
||
BREAK
|
||
The following two tests show that "137" is a symbol rather than a number:
|
||
|
||
$ (NUMBERP "137")
|
||
|
||
$ (SYMBOLP "137")
|
||
|
||
|
||
CONTINUE
|
||
Symbols and numbers are collectively called ATOMs to suggest their
|
||
indivisibility by ordinary means. The primitive recognizer function ATOM
|
||
returns T if its argument is an atom (i.e. either a symbol or a number);
|
||
otherwise is returns NIL. For example:
|
||
|
||
$ (ATOM 'APPLE)
|
||
|
||
$ (ATOM 123)
|
||
|
||
$ (ATOM '(DOG CAT COW))
|
||
|
||
$ (ATOM '())
|
||
|
||
|
||
CONTINUE
|
||
Sometimes you may wish to refer to a symbol itself rather than its value. In
|
||
muLISP, the apostrophe character is used as a quote mark to suppress the
|
||
evaluation of a symbol. For example:
|
||
|
||
$ (SETQ FOO 1492)
|
||
|
||
$ FOO
|
||
|
||
$ 'FOO
|
||
|
||
Note that the apostrophe is different from the "back accent" or "accent grave"
|
||
character, `, which also occurs on some terminals.
|
||
|
||
During this break, use SETQ and the quote mark to set the value of FOO back to
|
||
itself (i.e. make it be an auto-quoted symbol).
|
||
|
||
BREAK
|
||
The following restores the value of FOO to be itself:
|
||
|
||
$ (SETQ FOO 'FOO)
|
||
|
||
$ FOO
|
||
|
||
|
||
CONTINUE
|
||
The third primitive muLISP data object we shall discuss are Conses. A cons
|
||
is a nonatomic data object that points to two other data objects. The name
|
||
"cons" comes from the constructor function CONS discussed in the earlier
|
||
lessons.
|
||
|
||
Data can be stored in the computer's memory. The location where a data item
|
||
is stored is called its ADDRESS. An address is analogous to a street address
|
||
on a mailbox. The data stored there is analogous to mail in the mailbox. As
|
||
with mailboxes, the contents of computer memory can change over time.
|
||
|
||
Suppose we wish to represent the cons consisting of the symbol BILBO and his
|
||
age 31. We could store the symbol BILBO beginning at location 7, his age 31
|
||
at location 2, and beginning at location 4 we could store a cons consisting
|
||
of the pair of addresses 7 and 2:
|
||
|
||
Address: 1 2 3 4 5 6 7
|
||
+-----+-----+-----+-----+-----+-----+-----+---
|
||
Contents: | | 31 | | 7 | 2 | |BILBO|
|
||
+-----+-----+-----+-----+-----+-----+-----+---
|
||
|
||
CONTINUE
|
||
muLISP manages the specific placement of data within memory automatically, so
|
||
all we care about is the specific primitive symbols and numbers together with
|
||
the way they are connected. muLISP keeps track of addresses such as 7 and 2
|
||
in our example, but for us they are a distraction.
|
||
|
||
The following "box-car" representation of a cons suppresses such irrelevant
|
||
detail:
|
||
|
||
+-----+-----+
|
||
| . | . |
|
||
+-/---+---\-+
|
||
/ \
|
||
/ \
|
||
BILBO 31
|
||
|
||
|
||
CONTINUE
|
||
If you have seen one box-car, you have seen them all. So, to reduce clutter,
|
||
I henceforth represent conses by a dot at the vertices in my diagrams. For
|
||
example:
|
||
|
||
.
|
||
/ \
|
||
/ \
|
||
BILBO 31
|
||
|
||
Since each cons has exactly two "branches", such diagrams are called binary
|
||
trees.
|
||
|
||
|
||
CONTINUE
|
||
Although a linked collection of conses is best envisioned by humans as a
|
||
binary tree structure, a linearized representation of conses is more suitable
|
||
for a computer programming language.
|
||
|
||
One of the linear representations recognized by muLISP is the so-called DOT
|
||
notation. In this notation, a cons is represented by a left parenthesis, a
|
||
data item, a period, a data item, and a right parenthesis. For example, the
|
||
cons
|
||
|
||
.
|
||
/ \
|
||
/ \
|
||
BILBO 31
|
||
|
||
is represented in DOT notation as:
|
||
|
||
(BILBO . 31)
|
||
|
||
CONTINUE
|
||
The left element of a cons is called the CAR of the cons. The right element
|
||
is called the CDR of the cons. The elements of a cons can be any data object
|
||
including another cons. For example, BILBO's last name can be included in our
|
||
binary tree as:
|
||
|
||
.
|
||
/ \
|
||
/ \
|
||
. 31
|
||
/ \
|
||
/ \
|
||
BILBO BAGGINS
|
||
|
||
The equivalent dot notation representation of this tree is:
|
||
|
||
((BILBO . BAGGINS) . 31)
|
||
|
||
|
||
CONTINUE
|
||
Let's add the fact that BILBO is a hobbit to our binary tree:
|
||
|
||
.
|
||
/ \
|
||
/ \
|
||
. HOBBIT
|
||
/ \
|
||
/ \
|
||
. 31
|
||
/ \
|
||
/ \
|
||
BILBO BAGGINS
|
||
|
||
Before continuing think how this three cons binary tree would be represented
|
||
using dot notation.
|
||
|
||
CONTINUE
|
||
The tree is represented in dot notation as:
|
||
|
||
(((BILBO . BAGGINS) . 31) . HOBBIT)
|
||
|
||
An alternative binary tree structure for this information is the one
|
||
corresponding to:
|
||
|
||
((BILBO . BAGGINS) . (31 . HOBBIT))
|
||
|
||
Sketch the corresponding binary tree diagram on a piece of paper, then hold it
|
||
close to my face so I can check it out.
|
||
|
||
_____
|
||
/ \
|
||
>| O.O |<
|
||
| \=/ |
|
||
\___/
|
||
|
||
CONTINUE
|
||
Oh well, my eyes must be getting bad. It should have looked something like
|
||
this:
|
||
.
|
||
/ \
|
||
/ \
|
||
/ \
|
||
. .
|
||
/ \ / \
|
||
/ \ / \
|
||
BILBO BAGGINS 31 HOBBIT
|
||
|
||
|
||
From this discussion it should be clear that linked conses can be used to
|
||
represent virtually any tree structured data.
|
||
|
||
|
||
CONTINUE
|
||
It is often most natural to represent a collection of conses as a LIST of data
|
||
objects rather than as a deeply nested binary tree. For example, the elements
|
||
of a set are usually displayed as a list.
|
||
|
||
muLISP represents a list as a linked collection of conses whose CAR cells
|
||
point to the members of the lists and whose CDR cells point to the next cons.
|
||
The linked list is terminated by a CDR cell that points to NIL. For example:
|
||
.
|
||
/ \
|
||
/ \
|
||
object1 .
|
||
/ \
|
||
/ \
|
||
object2 .
|
||
.
|
||
.
|
||
/ \
|
||
/ \
|
||
objectN NIL
|
||
|
||
CONTINUE
|
||
When this binary tree is rotated 45 degrees counterclockwise, it is easier to
|
||
see why it can be used to represent a list of data objects:
|
||
|
||
.--------.--- . . . ---.----- NIL
|
||
| | |
|
||
| | |
|
||
object1 object2 objectN
|
||
|
||
The linear structure of lists suggests an external printed representation that
|
||
is much more readable than the equivalent dot notation representation. Thus
|
||
muLISP will automatically display the above object using LIST notation:
|
||
|
||
(object1 object2 ... objectN)
|
||
|
||
rather than using dot notation:
|
||
|
||
(object1 . (object2 . ... (objectN . NIL) ...))
|
||
|
||
CONTINUE
|
||
The muLISP object display functions use list notation where possible and dot
|
||
notation where necessary. Thus, a structure of the form
|
||
.
|
||
/ \
|
||
/ \
|
||
object1 .
|
||
/ \
|
||
/ \
|
||
object2 .
|
||
.
|
||
.
|
||
/ \
|
||
/ \
|
||
objectN atom
|
||
|
||
where <atom> is not the symbol NIL, is displayed in a mixed notation as:
|
||
|
||
(item1 item2 - - - itemN . atom)
|
||
|
||
|
||
CONTINUE
|
||
The muLISP input reader function accepts list notation, dot notation, and
|
||
mixed notation. Moreover, any of the elements of a list can themselves be
|
||
either lists or more general expressions. The following examples show how
|
||
muLISP displays a few expressions:
|
||
|
||
$ '(DOG . (CAT . (COW . PIG)))
|
||
|
||
$ '((AGE . 34) . (HOBBIES . (SWIMMING . THINKING)))
|
||
|
||
|
||
CONTINUE
|
||
During this lesson we have described the three primitive muLISP data objects:
|
||
Symbols, Numbers, and Conses. The following are the main points to remember:
|
||
|
||
1. Symbols: Each symbol has an associated print name string, a value, a
|
||
property list, and a function definition. Symbols containing special
|
||
characters can be entered using quoted strings. SETQ is the function
|
||
most commonly used to assign a value to a symbol.
|
||
|
||
2. Numbers: A number is a positive or negative rational number. NUMBERP
|
||
is used to recognize numbers. Numbers are subdivided into integers or
|
||
ratios. INTEGERP is used to recognize integers.
|
||
|
||
3. Conses: Conses are used to form binary tree structures that can be
|
||
represented using dot notation, list notation, or mixed notation.
|
||
|
||
This concludes muLISP lesson #3.
|
||
|
||
|
||
CONTINUE
|
||
$ (RDS)
|
||
|