A Lisp Machine with Very Compact Programs
Total Page:16
File Type:pdf, Size:1020Kb
Session 25 Hardware and Software for Artificial Intelligence A LISP MACHINE WITH VERY COMPACT PROGRAMS L. Peter Deutsch Xerox corporation, Palo Alto Research center (PARC) Palo Alto, California 94304 Abstract Data Types This paper presents a machine designed for LISP has many data types (e.g. list, compact representation and rapid execution symbolic atom, integer) but no declarations. of LISP programs. The machine language is a The usual implementation of languages with factor of 2 to 5 more compact than this property affixes a tag to each datum to S-expressions or conventional compiled code, indicate its type, in LISP, however, the , and the.compiler is extremely simple. The vast majority of data are pointers to lists encoding scheme is potentially applicable to or atoms, and it would be wasteful to leave data as well as program. The machine also room for a full word plus tag (the space provides for user-defined data structures. needed for an integer datum, for example) in every place where a datum can appear such as Introduction the CAR and CDR of list cells. Consequently, in BBN-LISP every datum is a Pew existing computers permit convenient or pointer; integers, strings, etc. are all efficient implementation of dynamic storage referenced indirectly. Storage is allocated in quanta, and each quantum holds data of allocation, recursive procedures, or only one type, so what type of object a operations on data whose type is represented given pointer references is just a function explicitly at run time rather than of the object's address, i.e. the pointer determined at compile time. This mismatch itself. between machine and language design plagues every implementor of languages designed for manipulation of structured information. The chief drawback of this scheme is that Neither of the usual software solutions to every built-in function which produces a this problem is entirely satisfactory. number as a result (such as PLUS, the Interpretive systems are easy to build and addition function) must allocate a word to flexible, but intrinsically inefficient; hold the result. This leads to frequent, compilers which approach the efficiency of time-consuming garbage collections. those for conventional languages are hard to BBN-LISP circumvents this problem for the write and often force the implementor (and most part by permanently storing all the user) to sacrifice valuable but expensive integers from -1536 to +1535 in consecutive language features for the sake of cells and just returning a pointer to one of efficiency. On many machines compiled code these cells if a numerical result is in this also occupies at least as much space as a range, rather than allocating a new cell. structured representation of the source In MicroLISP, which is intended as a program. reasonably efficient numerical language, data on the stack (temporary results and An alternative approach to this problem is variable bindings) carry a type tag to design machines whose code structure more identifying them as integers, floating point closely resembles that of their major numbers, or pointers. In this way, long programming language(s). This approach of numerical calculations can take place tailoring the machine to the language was without any consumption of allocated space. first used in the Burroughs B5000 and successor machines, which were designed to No existing LISP system permits the user to execute ALGOL 60 programs.' In recent years, define his own packed data structures. the availability of microprogrammed MicroLISP includes such a facility, since it processors and the continuing decline in the can be made inexpensive when implemented in cost of processor hardware and design have the machine language and since its absence prompted several experiments of this sort at from LISP is one of the reasons most universities* and at least one successful frequently cited for choosing other experiment by a large company* and one languages for complex symbolic computation. unsuccessful new commercial venture.3 The details are presented in Appendix A, since they are somewhat peripheral to the The present paper describes a machine design rest of this paper. It is worth noting that for efficient representation and execution the scheme could be implemented within of BBN-LISP programs. BBN-LISP is an BBN-LISP and even lends itself to efficient interactive system developed from the Lisp compilation in the usual case. language.* 10 Readers unfamiliar with LISP should consult weissman's excellent primer5; Control and Binding Structure some details particular to BBN-LISP appear in the next sections of this paper. A MicroLISP uses a single stack structure for both control and variable bindings, complete and well-maintained but voluminous 1 reference manual for BBN-LISP is also essentially as described in a recent paper. available." The machine design presented A function call allocates a "basic frame" here will be referred to as MicroLISP, a for the arguments and a "frame extension" name intended to connote both code for control information and temporary compactness and possible microprogrammed values* The basic frame contains the implementation. function name, the argument values 697 (bindings), and a pointer to the argument In both BBN-LISP and MicroLISP, all variable names. The frame extension holds a pointer bindings appear in the basic frame. In to the caller's frame extension and a BBN-LISP half of each word in the basic variety of other bookkeeping information. frame is reserved for the name, In The FUNARG capability of LISP 1.5, i.e. the MicroLISP, the basic frame contains a single ability to construct a data object pointer to a table of names (the LNT; see comprising a function and a binding below). Either scheme requires that any environment, is provided through a primitive PROG or open LAMBDA which does not function which creates an "environment constitute the entire body of a function be descriptor" pointing to a specified frame. made a separate subfunction, since PROG As long as there are accessible references variables are bound at the time the frame is to this descriptor, the frame continues to created, i.e. when the function is entered. exist. Environment descriptors also allow The MicroLISP scheme may slow down free the user to construct cooperating sequential variable searches, since a name table may processes (coroutines); the stack becomes not be in core any longer when the search tree-structured rather than linear, as in wants to scan it. Its advantages are that the Burroughs B6500.1* it is not necessary to insert the name of each variable at function entry time, and BBN-LISP, like most programming languages, that the entire word is available for recognizes two kinds of accesses to holding the binding, which (with the help of variables: "load" and "store". This duality a few type bits elsewhere in the frame) may actually exists for data structures as well thus be a full-word integer or real number. (CAR-RPLACA, GET-POT, etc.) but is not treated systematically. MicroLISP Code Design systematizes this concept by allowing a function to have, in effect, two Conventional machines generally take the definitions, one for the (normal) "load" attitude that it must be convenient for any context, one for the "store" context. The instruction to reference any word in the SET function is extended so that if the overall address space. This approach tends first argument is a list to produce instruction formats in which a (fn argl ... argn) large fraction (half or more) of the bits rather than a variable, the function fn is are devoted to a memory address. MicroLISP called in "store" mode with arguments argl takes advantage of the observed fact that a ... argn and newvalue (the second argument given LISP function references rather few of SET). SETQ is alsO extended in the functions and variables and therefore can obvious way, but is not particularly useful. make do with very short addresses which just A more useful function is index a global table (of commonly used (SETFQ (f n argl ... argn) newvalue) functions) or a function-local table (of which quotes the function name and evaluates local variables and less common functions). everything else. This allows RPLACA, for Furthermore, a given name is usually only example, to be defined as used as either a function or a variable, not (LAMBDA (X Y) (SETFQ (CAR X) Y>) - both. MicroLISP tags each name in the tables with a function/variable flag, which The semantics of variables are simple in eliminates the need for levels of list principle: search the current basic frame, structure as a syntactic device, and tags then the caller's frame, etc. for a binding functions with an argument count, which of a variable with the desired name; if none eliminates the need for sublists as scope is found, consult the "value cell" of the delimiters. Thus MicroLISP code is variable; if this contains the special value essentially a string of byte-sized NOBIND, the variable is unbound. (In fact, instructions, representing the original the search follows a chain through an s-expression in postfix form, where most "access link" pointer in the frame extension bytes reference either a "global name table" rather than the caller pointer or (GNT) or a "local name table" (LNT) as just "control link", to cover application of described. FUNARGs.) MicroLISP (and compiled BBN LISP) actually use three variations of this The LNT actually has additional internal searching strategy depending on the structure: argument names come first, then situation. Searching for the arguments of PROG and free variables, then everything the current function is pointless: their else. The "binding" of a free variable is a relative locations in the basic frame are pointer to the true binding, and the known to the compiler and they can be variable searching algorithm uses this accessed by indexing.