Structures This document attempts to identify the issues involved in implementing Common Lisp structures and (secondarily) suggest potential solutions. Issues. Typing: Any instance of a structure (that is :named and doesn't specify a :type) must return the structure name from type-of. Currently in Interlisp this is true only of datatypes. However, there is a (relatively difficult to change) limit of 255 datatypes which is too restrictive limit on the number of structures. Representation: Any representation is subject to the ability to implement :type specifications (legal choices are vector (same as (vector t)), (vector element-type), and list). Note that specifying :type "prevents the structure name from becoming a valid type specifier recognizable by typep". Structures who specify a :type cannot :include a structure with a different :type. This means that accessors can be inherited from a supertype (though they would have had to be parameterised to allow for :includes and :initial-offsets.) We must correctly handle notinline declarations. Currently, all datatype operations are inline. Default initialization forms are to be evaluated in the lexical environment of the defstruct. CommonLoops: Do we want to consider the future importation of CommonLoops? I think that we may be able to save a lot of work in the future by thinking about this now. Typechecking: When assigning a typed field it is optional whether or not to typecheck the new value (or initialization form). When assigning any field it is optional whether or not to typecheck the record instance. NonIssues. Are there hidden complexities about :conc-name, :constructor, (slot-option) :read-only [ just verify that a field is writable before generating the accessor code] , :predicate, :constructor? They seem mostly straightforward. Environment Issues: Programming tools such as Masterscope should understand CL structures. This is not entirely straightforward, since it must understand the transitive closure of :include. (e.g. to answer ". who uses foo as a field" it should recognize not just uses of BAZ-FOO but X-FOO for all X that include BAZ (and everything that includes X, etc.) II. Solution overview (issues to parts relations) Three possible ways of doing default defstruct, as in (defstruct foo a b c). Don't just count pros & cons below: a) use datatypes pro: already implemented, sort of efficient access right semantics (type-of works) its what Interlisp records turn into opportunity to get rid of Interlisp records eventually con: datatypes don't :include not enough datatypes CML's implementation is incomplete. b) use some new kind of named vectors con: type-of has to recognize named vectors different from unnamed requires getting into llhunk code etc. new hunk types etc. doesn't handle packed structures well since hunks are homogeneous c) use some variation on Common loops scheme c1) use common loops pro: neat, future direction con: how much of CommonLoops need be imported to use its DEFSTRUCT. c2) use just small piece of common loops, e.g. common loops compatible but not the rest of the hair III. Parts of above options. a) extend datatypes. 1. Dependencies. to allow :include in datatypes we require the following microcode change: DTEST will now succeed if the instance is a member of a subtype of the specified datatype. [this is already present in \DTEST.UFN in n>]. TYPEP (the Interlisp-D opcode) can remain in its current use, since it is only suitable for datatypes whose number can't change (hence small datatype numbers). However, with DATATYPES like STREAM, the compiler already generates DTEST's instead of TYPEP's. Why? Field accessors will be funcall'able objects specified in the definition cell of the accessors. [ This fields need to be worked out exactly with Jan to agree with the array code] Suggested fields for an accessor are datatype 12 bits element type 2 bits {bit description / word length} 8 bits word offset 8 bits($$(((MODERN GACHA  TIMESROMAN TERMINAL TERMINAL MODERN MODERN MODERN  ,&ÅK#   Ry >a¨ŒJ $–Q2q#"'9&&@=D-GeJ‘ bS%'ŋŸzē