75 lines
50 KiB
Plaintext
75 lines
50 KiB
Plaintext
1
|
||
|
||
Interlisp-D Reference Manual
|
||
1
|
||
|
||
Interlisp-D Reference Manual
|
||
2. LITATOMS (SYMBOLS)
|
||
1
|
||
|
||
2. LITATOMS (SYMBOLS)
|
||
1
|
||
|
||
|
||
"2"2. LITATOMS (SYMBOLS)
|
||
6
|
||
|
||
A litatom (for "literal atom") is an object which conceptually consists of a print name, a value, a function definition, and a property list. Litatoms are also known as "symbols" in Common Lisp. For clarity, we will use the term "symbol".
|
||
A symbol is read as any string of non-delimiting characters that cannot be interpreted as a number. The syntactic characters that delimit symbols are called "separator" or "break" characters (see Chapter 25) and normally are space, end-of-line, line-feed, left parenthesis (, right parenthesis ), double quote ", left square bracket [, and right square bracket ]. However, any character may be included in a symbol by preceding it with the character %. Here are some examples of symbols:
|
||
A wxyz 23SKIDDOO %] 3.14125 + 17
|
||
Long%Litatom%With%Embedded%Spaces
|
||
(LITATOM(LITATOM (Function) NIL NIL ("2") 1) X) [Function]
|
||
Returns T if X is a symbol, NIL otherwise. Note that a number is not a symbol.
|
||
(LITATOM NIL) = T
|
||
(ATOM (ATOM% (Function) NIL NIL ("2") 1)X) [Function]
|
||
Returns T if X is an atom (i.e., a symbol or a number); NIL otherwise.
|
||
Warning: (ATOM X) is NIL if X is an array, string, etc. In many dialects of Lisp, the function ATOM is defined equivalent to the Interlisp function NLISTP.
|
||
(LISTP NIL) = NIL
|
||
Symbols are printed by PRINT and PRIN2 as a sequence of characters with %s inserted before all delimiting characters (so that the symbol will read back in properly). Symbols are printed by PRIN1 as a sequence of characters without these extra %s. For example, the symbol consisting of the five characters A, B, C, (, and D will be printed as ABC%(D by PRINT and ABC(D by PRIN1.
|
||
Symbols can also be constructed by PACK, PACK*, SUBATOM, MKATOM, and GENSYM (which uses MKATOM).
|
||
Symbols are unique. In other words, if two symbols print the same, they will always be EQ. Note that this is not true for strings, large integers, floating-point numbers, and lists; they all can print the same without being EQ. Thus, if PACK or MKATOM is given a list of characters corresponding to a symbol that already exists, they return a pointer to that symbol, and do not make a new symbol. Similarly, if the read program is given as input a sequence of characters for which a symbol already exists,it returns a pointer to that symbol.
|
||
Symbols are limited to 255 characters . Attempting to create a larger symbol either via PACK or by typing one in (or readying from a file) will cause an error: ATOM TOO LONG.
|
||
Using Symbols as Variables
|
||
1
|
||
|
||
Symbols are commonly used as variables. Each symbol has a "top level" variable binding, which can be an arbitrary Interlisp object. Symbols may also be given special variable bindings within PROGs or function called, which only exist for the duration of the function. When a symbol is evaluated, the "current" variable binding is returned. This is the most recent special variable binding, or the top level binding if the symbol has not been rebound. SETQ is used to change the current binding.. For more information on variable bindings in Interlisp, see Chapter 11.
|
||
Note: The compiler (see Chapter 18) treats variables somewhat differently than the interpreter, and the user has to be aware of these differences when writing functions that will be compiled. For example, variable references in compiled code are not checked for NOBIND, so compiled code will not generate unbound atom errors. In general, it is better to debug interpreted code, before compiling it for speed. The compiler offers some facilities to increase the efficiency of variable use in compiled functions. Global variables can be defined so that the entire stack is not searched at each variable reference. Local variables allow compiled functions to access variable binds which are not on the stack, which reduces variable conflicts, and also makes variable lookup faster.
|
||
By convention, a symbol whose top level binding is to the symbol NOBIND is considered to have no top level binding. If a symbol has no local variable bindings, and its top level value is NOBIND, attemptint to evaluate it will cause an unbound atom error.
|
||
The two symbols T and NIL always evaluate to themselves. Attempting to change the binding of T or NIL with the functions below will generate the error ATTEMPT TO SET T or ATTEMPT TO SET NIL.
|
||
The following functions (except BOUNDP) will also generate the error ARG NOT LITATOM, if not given a symbol.
|
||
(BOUNDP(BOUNDP (Function) NIL NIL ("2") 2) VAR) [Function]
|
||
Returns T if VAR has a special variable binding (even if bound to NOBIND), or if VAR has a top level value other than NOBIND; otherwise NIL. In other words, if X is a symbol, (EVAL X) will cause an UNBOUND ATOM error if and only if (BOUNDP X) returns NIL.
|
||
(SET(SET (Function) NIL NIL ("2") 2) VAR VALUE) [NoSpread Function]
|
||
Sets the "current" variable binding of VAR to VALUE, and returns VALUE.
|
||
SET is a normal function, so both VAR and VALUE are evaluated before it is called. Thus, if the value of X is B, and value of Y is C, then (SET X Y) would result in B being set to C, and C being returned as the value of SET.
|
||
(SETQ(SETQ (Function) NIL NIL ("2") 2) VAR VALUE) [NoSpread Function]
|
||
Nlambda version of SET. VAR is not evaluated, VALUE is. Thus, if the value of X is B and the value of Y is C, (SETQ X Y) would result in X (not B) being set to C, and C being returned.
|
||
Note: Since SETQ is an nlambda, neither argument is evaluated during the calling process. However, SETQ itself calls EVAL on its second argument. As a result, typing (SETQ VAR FORM) and SETQ(VAR FORM) to the Interlisp Executive are equivalent: in both cases VAR is not evaluated, and FORM is.
|
||
(SETQQ(SETQQ (Function) NIL NIL ("2") 2) VAR VALUE) [NoSpread Function]
|
||
Like SETQ except that neither argument is evaluated, e.g., (SETQQ X(A B C)) sets X to (A B C).
|
||
(PSETQ(PSETQ (Macro) NIL NIL ("2") 3) VAR1 VALUE1 ... VARN VALUEN) [Macro]
|
||
Does a SETQ in parallel of VAR1 (unevaluated) to the value of VALUE1, VAR2 to the value of VALUE2, etc. All of the VALUE1terms are evaluated before any of the assignments. Therefore, (PSETQ A B B A) can be used to swap the values of the variables A and B.
|
||
(GETTOPVAL(GETTOPVAL (Function) NIL NIL ("2") 3) VAR) [Function]
|
||
Returns the top level value of VAR (even if NOBIND), regardless of any intervening local bindings.
|
||
(SETTOPVAL(SETTOPVAL (Function) NIL NIL ("2") 3) VAR VALUE) [Function]
|
||
Set the top level value of VAR to VALUE, regardless of any intervening bindings, and returns VALUE.
|
||
A major difference betweenvarious Interlisp implementations is the way that variable bindings are implemented. Interlisp-10 and Interlisp-Jerico use what is called "shallow" binding. Interlisp-D and Interlisp-VAX use what is called "deep" binding.
|
||
In a deep binding system, a variable is bound by saving on the stack the variable's new value. When a variable is accessed, its value is found by searching the stack for the most recent binding. If the variable is not found on the stack, the top level binding is retrieved from a "value cell" associated with the variable.
|
||
In a "shallow" binding system, a variable is bound by saving on the stack the variable name and the variable's old value, and putting the value in the variable's value cell. When a variable is accessed, its value is always found in its value cell.
|
||
GETTOPVAL and SETTOPVAL are less efficient in a shallow binding system, because they have to search the stack for rebindings. It is more economical to simply rebind variables. In a deep binding system, GETTOPVAL and SETTOPVAL are very efficient since they do not have to search the stack, but can simply access the value cell directly.
|
||
GETTOPVAL and SETTOPVAL can be used to access a variable's value cell, in either a shallow or deep binding system.
|
||
(GETATOMVAL(GETTOPVAL (Function) NIL NIL ("2") 3) VAR) [Function]
|
||
Returns the value in the value cell of VAR. In a shallow binding system, this is the same as (EVAL ATM), or simply VAR. In a deep binding system, this is the same as (GETTOPVAL VAR).
|
||
(SETATOMVAL(SETATOMVAL (Function) NIL NIL ("2") 3) VAR VALUE) [Function]
|
||
Sets the value cell of VAR to VALUE. In a shallow binding system, this is the same as SET. In a deep binding system, this is the same as SETTOPVAL.
|
||
Function Definition Cells
|
||
1
|
||
|
||
Each symbol has a function definition cell, which is accessed when a symbol is used as a function. The mechanism for accessing and setting the function definition cell of a symbol is described in Chapter 10.
|
||
Property Lists
|
||
1
|
||
|
||
Each symbol has an associated property list, which allows a set of named objects to be associated with the symbol. A property list associates a name (known as a "property name" or "property") with an arbitrary object (the "property value" or "value"). Sometimes the phrase "to store on the property X" is used, meaning to place the indicated information on a property list under the property name X.
|
||
Property names are usually symbols or numbers, although no checks are made. However, the standard property list functions all use EQ to search for property names, so they may not work with non-atomic property names. The same object can be used as both a property name and a property value.
|
||
Note: Many symbols in the system already have property lists, with properties used by the compiler, the break package, DWIM, etc. Be careful not to clobber such system properties. The variable SYSPROPS is a list of property names used by the system.
|
||
The functions below are used to manipulate the property lists of symbols. Except when indicated, they generate the error ARG NOT LITATOM, if given an object that is not a symbol.
|
||
(GETPROP(GETPROP (Function) NIL NIL ("2") 4) ATM PROP) [Function]
|
||
Returns the property value for PROP from the property list of ATM. Returns NIL if ATM is not a symbol, or PROP is not found. GETPROP also returns NIL if there is an occurrence of PROP but the corresponding property value is NIL. This can be a source of program errors.
|
||
Note: GETPROP used to be called GETP.
|
||
(PUTPROP(PUTPROP (Function) NIL NIL ("2") 4) ATM PROP VAL) [Function]
|
||
Puts the property PROP with value VAL on the property list of ATM. VAL replaces any previous value for the property PROP on this property list. Returns VAL.
|
||
(ADDPROP(ADDPROP (Function) NIL NIL ("2") 4) ATM PROP NEW FLG) [Function]
|
||
Adds the value NEW to the list which is the value of property PROP on the property list of the ATM. If FLG is T, NEW is CONSed onto the front of the property value of PROP; otherweise, it is NCONCed on the end (using NCONC1). If ATM does not have a property PROP, or the value is not a list, then the effect is the same as (PUTPROP ATM PROP (LIST NEW)). ADDPROP returns the (new) property value. Example:
|
||
¬(PUTPROP 'POCKET 'CONTENTS NIL)
|
||
(NIL)
|
||
¬(ADDPROP 'POCKET 'CONTENTS 'COMB)
|
||
(COMB)
|
||
¬(ADDPROP 'POCKET 'CONTENTS 'WALLET)
|
||
(COMB WALLET)
|
||
(REMPROP(REMPROP (Function) NIL NIL ("2") 4) ATM PROP) [Function]
|
||
Removes all occurrences of the property PROP (and its value) from the property list of ATM. Returns PROP if any were found, otherwise NIL.
|
||
(REMPROPLIST(REMPROPLIST (Function) NIL NIL ("2") 4) ATM PROPS) [Function]
|
||
Removes all occurrences of all properties on the list PROPS (and their corresponding property values) from the property list of ATM. Returns NIL.
|
||
(CHANGEPROP(CHANGEPROP (Function) NIL NIL ("2") 4) X PROP1 PROP2) [Function]
|
||
Changes the property name of property PROP1 to PROP2 on the property list of X (but does not affect the value of the property). Returns X, unless PROP1 is not found, in which case it returns NIL.
|
||
(PROPNAMES(PROPNAMES (Function) NIL NIL ("2") 5) ATM) [Function]
|
||
Returns a list of the property names on the property list of ATM.
|
||
(DEFLIST(DEFLIST (Function) NIL NIL ("2") 5) L PROP) [Function]
|
||
Used to put values under the same property name on the property lists of several symbols. L is a list of two-element lists. The first element of each is a symbol, and the second element is the property vqalue of the property PROP. Returns NIL. For example:
|
||
(DEFLIST '(FOO MA)(BAR CA)(BAZ RI)) 'STATE)
|
||
puts MA on FOO's STATE property, CA on BAR's STATE property, and RI on BAZ's STATE property.
|
||
Property lists are conventionally implemented as lists of the form
|
||
(NAME1 VALUE1 NAME2 VALUE2...)
|
||
although the user can store anything as the property list of a symbol. However, thge functions which manipulate property lists observe this convention by searching down the property lists two CDRs at a time. Most of these functions also generate the error ARG NOT LITATOM if given an argument which is not a symbol, so they cannot be used directly on lists. (LISTPUT, LISTPUT1, LISTGET, and LISTGET1 are functions similar to PUTPROP and GETPROP that work directly on lists. See Chapter 3.) The property lists of symbols can be directly accessed with the following functions.
|
||
(GETPROPLIST(GETPROPLIST (Function) NIL NIL ("2") 5) ATM) [Function]
|
||
Returns the property list of ATM.
|
||
(SETPROPLIST(SETPROPLIST (Function) NIL NIL ("2") 5) ATM LST) [Function]
|
||
If ATM is a symbol, sets the property list of ATM to be LST, and returns LST as its value.
|
||
(GETLIS(GETLIS (Function) NIL NIL ("2") 5) X PROPS) [Function]
|
||
Searches the property list of X, and returns the property list as of the first property on PROPS that it finds. For example:
|
||
¬(GETPROPLIST 'X)
|
||
(PROP1 A PROP3 B A C)
|
||
¬(GETLIS 'X '(PROP2 PROP3))
|
||
(PROP3 B A C)
|
||
Returns NIL if no element on props is found. X can also be a list itself, in which case it is searched as described above. If X is not a symbol or a list, returns NIL.
|
||
Print Names
|
||
1
|
||
|
||
Each symbol has a print name, a string of characters that uniquely identifies that symbol. The term "print name" has been extended, however, to refer to the characters that are output when any object is printed. In Interlisp, all objects have print names, although only symbols and strings have their print name explicitly stored. This section describes a set of functions which can be used to access and manipulate the print names of any object, though they are primarily used with the print names of symbols.
|
||
The print name of an object is those characters that are output when the object is printed using PRIN1, e.g., the print name of the symbol ABC%(D consists of the five characters ABC(D. The print name of the list (A B C) consists of the seven characters (A B C) (two of the characters are spaces).
|
||
Sometimes we have occasion to refer to a "PRIN2-name". The PRIN2-name of an object is those characters output when the object is printed using PRIN2. Thus the PRIN2-name of the symbol ABC%(D is the six characters ABC%(D. The PRIN2-name depends on what readtable is being used (see Chapter 25), since this determines where %s will be inserted. Many of the functions below allow either print names of PRIN2-names to be used, as specified by FLG and RDTBL arguments. If FLG is NIL, print names are used. Otherwise, PRIN2-names are used, computed with respect to the readtable RDTBL (or the current readtable, if RDTBL = NIL).
|
||
Note: The print name of an integer depends on the setting of RADIX (see Chapter 25). The functions described in this section (UNPACK, NCHARS, etc.) define the print name of an integer as though the radix was 10, so that (PACK (UNPACK 'X9)) will always be X9 (and not X11, if RADIX is set to 8). However, integers will still be printed by PRIN1 using the current radix. The user can force these functions to use print names in the current radix by changing the setting of the variable PRXFLG (see Chapter 25).
|
||
(MKATOM(MKATOM (Function) NIL NIL ("2") 6) X) [Function]
|
||
Creates and returns an atom whose print name is the name as that of the string X or, if X is not a string, the same as that of (MKSTRING X). Examples:
|
||
(MKATOM '(A B C)) => %(A% B% C%)
|
||
(MKATOM "1.5" => 1.5
|
||
Note that the last example returns a number, not a symbol. It is a deeply-ingrained feature of Interlisp that no symbol can have the print name of a number.
|
||
(SUBATOM(SUBATOM (Function) NIL NIL ("2") 6) X N M) [Function]
|
||
Equivalent to (MKATOM (SUBSTRING X N M)), but does not make a string pointer (see Chapter 4). Returns an atom made from the Nth through Mth characters of the print name of X. If N or M are negative, they specify positions counting backwards from the end of the print name. Examples:
|
||
(SUBATOM "FOO1.5BAR" 4 6) => 1.5
|
||
(SUBATOM '(A B C) 2 -2) => A% B% C
|
||
(PACK(PACK (Function) NIL NIL ("2") 6) X) [Function]
|
||
If X is a list of atoms, PACK returns a single atom whose print name is the concatenation of the print names of the atoms in X. If the concatenated print name is the same as that of a number, PACK returns that number. For example:
|
||
(PACK '(A BC DEF G)) => ABCDEFG
|
||
(PACK '(1 3.4)) => 13.4
|
||
(PACK '(1 E -2)) => .01
|
||
Although X is usually a list of atoms, it can be a list of arbitrary Interlisp objects. The value of PACK is still a single atom whose print name is the concatenation of the print names of all the elements of X, e.g.,
|
||
(PACK '((A B) "CD")) => %(A% B%)CD
|
||
If X is not a list or NIL, PACK generates the error ILLEGAL ARG.
|
||
(PACK* X1 X2... XN(PACK* (Function) NIL NIL ("2") 6) ) [NoSpread Function]
|
||
Nospread version of PACK that takes an arbitrary number of arguments, instead of a list. Examples:
|
||
(PACK* 'A 'BC 'DEF 'G => ABCDEFG
|
||
(PACK* 1 3.4)) => 13.4
|
||
(UNPACK(UNPACK (Function) NIL NIL ("2") 7) X FLG RDTBL) [Function]
|
||
Returns the print name of X as a list of single-character atoms. Examples:
|
||
(UNPACK 'ABC5D) => (A B C 5 D)
|
||
(UNPACK "ABC(D") => (A B C %( D)
|
||
If FLG = T, the PRIN2-name of X is used (computed with respect to RDTBL). Examples:
|
||
(UNPACK 'ABC5D) => (A B C 5 D)
|
||
(UNPACK "ABC(D") => (A B C %( D)
|
||
Note: (UNPACK X) performs N CONSes, where N is the number of characters in the print name of X.
|
||
(DUNPACK X SCRATCHLIST FLG RDTBL(DUNPACK (Function) NIL NIL ("2") 7) ) [Function]
|
||
A destructive version of UNPACK that does not perform any CONSes but instead reuses the list SCRATCHLIST. If the print name is too long to fit in SCRATCHLIST, DUNPACK will extend it. If SCRATCHLIST is not a list, DUNPACK returns (UNPACK X FLG RDTBL).
|
||
(NCHARS X FLG RDTBL(NCHARS (Function) NIL NIL ("2") 7) ) [Function]
|
||
Returns the number of characters in the print name of X. If FLG = T, the PRIN2-name is used. Examples:
|
||
(NCHARS 'ABC) => 3
|
||
(NCHARS "ABC" T) => 5
|
||
Note: NCHARS works most efficiently on symbols and strings, but can be given any object.
|
||
(NTHCHAR X N FLG RDTBL(NTHCAR (Function) NIL NIL ("2") 7)) [Function]
|
||
Returns X, if X is a tail of the list Y; otherwise NIL. X is a tail of Y if it is EQ to 0 or more CDRs of Y.
|
||
(NTHCHAR 'ABC 2) => B
|
||
(NTHCHAR 15.6 2) => 5
|
||
(NTHCHAR 'ABC%(D -3 T) => %%
|
||
(NTHCHAR "ABC" 2) => B
|
||
(NTHCHAR "ABC" 2 T) => A
|
||
Note: NTHCAR and NCHARS work much faster on objects that actually have an internal representation of their print name, i.e., symbols and strings, than they do on numbers and lists, as they do not have to simulate printing.
|
||
(L-CASE(L-CASE (Function) NIL NIL ("2") 7) X FLG) [Function]
|
||
Returns a lowercase version of X. If FLG is T, the first letter is capitalized. If X is a string, the value of L-CASE is also a string. If X is a list, L-CASE returns a new list in which L-CASE is computed for each corresponding element and non-NIL tail of the original list. Examples:
|
||
(L-CASE 'FOO) => foo
|
||
(L-CASE 'FOO T) => Foo
|
||
(L-CASE "FILE NOT FOUND" T) => "File not found"
|
||
(L-CASE '(JANUARY FEBRUARY (MARCH "APRIL")) T)
|
||
=> '(January February (March "April"))
|
||
(U-CASE(U-CASE (Function) NIL NIL ("2") 8) X ) [Function]
|
||
Similar to L-CASE, except returns the uppercase version of X.
|
||
(U-CASEP(U-CASEP (Function) NIL NIL ("2") 8) X) [Function]
|
||
Returns T if X contains no lowercase letters; NIL otherwise.
|
||
(GENSYM(GENSYM (Function) NIL NIL ("2") 8) PREFIX ÿÿ |