Fix traceroot output for object directly referenced by stack
[sbcl.git] / PRINCIPLES
blob48f73b02e94e62ed57f37cb47578419c8c54512c
1 "In truth, I found myself incorrigible with respect to *Order*; and
2 now I am grown old and my memory bad, I feel very sensibly the want of
3 it. But, on the whole, though I never arrived at the perfection I had
4 been so ambitious of obtaining, but fell far short of it, yet I was,
5 by the endeavour, a better and happier man than I otherwise should
6 have been if I had not attempted it; as those who aim at perfect
7 writing by imitating the engraved copies, though they never reach the
8 wished-for excellence of those copies, their hand is mended by the
9 endeavor, and is tolerable while it continues fair and legible."
10   -- Benjamin Franklin in his autobiography
12 "'Signs make humans do things,' said Nisodemus, 'or stop doing things.
13 So get to work, good Dorcas. Signs. Um. Signs that say *No*.'"
14   -- Terry Pratchett, _Diggers_
16 There are some principles which I'd like to see used in the
17 maintenance of SBCL:
18 1. conforming to the standard
19 2. being maintainable
20    a. removing stale code
21    b. When practical, important properties should be made manifest in
22       the code. (Putting them in the comments is a distant second best.)
23       i. Perhaps most importantly, things being the same (in the strong 
24          sense that if you cut X, Y should bleed) should be manifest in
25          the code. Having code in more than one place to do the same
26          thing is bad. Having a bunch of manifest constants with hidden
27          relationships to each other is inexcusable. (Some current
28          heinous offenders against this principle are the memoizing
29          caches for various functions, and the LONG-FLOAT code.)
30       ii. Enforcing nontrivial invariants, e.g. by declaring the
31           types of variables, or by making assertions, can be very
32           helpful.
33    c. using clearer internal representations 
34       i. clearer names
35          A. more-up-to-date names, e.g. PACKAGE-DESIGNATOR instead
36             of PACKAGELIKE (in order to match terminology used in ANSI spec)
37          B. more-informative names, e.g. SAVE-LISP-AND-DIE instead
38             of SAVE-LISP or WRAPPER-INVALID rather than WRAPPER-STATE
39          C. families of names which correctly suggest parallelism,
40             e.g. CONS-TO-CORE instead of ALLOCATE-CONS, in order to 
41             suggest the parallelism with other FOO-TO-CORE functions
42       ii. clearer encodings, e.g. it's confusing that WRAPPER-STATE in PCL
43           returns T for valid and any other value for invalid; could
44           be clarified by changing to WRAPPER-INVALID returning a 
45           generalized boolean; or e.g. it's confusing to encode things
46           as symbols and then use STRING= SYMBOL-NAME instead of EQ 
47           to compare them.
48       iii. clearer implementations, e.g. cached functions being
49            done with HASH-TABLE instead of hand-coded caches
50    d. informative comments and other documentation
51       i. documenting things like the purposes and required properties
52          of functions, objects, *FEATURES* options, memory layouts, etc.
53       ii. not using terms like "new" without reference to when.
54           (A smart source code control system which would let you
55           find when the comment was written would help here, but
56           there's no reason to write comments that require a smart
57           source code control system to understand..)
58    e. using functions instead of macros where appropriate
59    f. maximizing the amount of stuff that's (broadly speaking) "table
60       driven". I find this particularly helpful when the table describes 
61       the final shape of the result (e.g. the package-data-list.lisp-expr
62       file), replacing a recipe for constructing the result (e.g. various
63       in-the-flow-of-control package-manipulation forms) in which the
64       final shape of the result is only implicit. But it can also be very
65       helpful any time the table language can be just expressive enough
66       for the problem at hand. 
67    g. using functional operators instead of side-effecting operators
68       where practical
69    h. making it easy to find things in the code
70       i. defining things using constructs which can be understood by etags
71    i. using the standard library where possible
72       i. instead of hand-coding stuff
73          (My package-data-list.lisp-expr stuff may be a bad example as of
74          19991208, since the system has evolved to the point where it
75          might be possible to replace my hand-coded machinery with some
76          calls to DEFPACKAGE.)
77    j. more-ambitious dreams..
78       i. fixing the build process so that the system can be bootstrapped
79          from scratch, so that the source code alone, and not bits and
80          pieces inherited from the previous executable, determine the 
81          properties of the new executable
82       ii. making package dependencies be a DAG instead of a mess, so 
83           the system could be understood (and rebuilt) in pieces
84       iii. moving enough of the system into C code that the Common Lisp
85            LOAD operator (and all the symbol table and FOP and other
86            machinery that it depends on) is implemented entirely in C, so
87            that GENESIS would become unnecessary (because all files could
88            now be warm loaded)
89 3. being portable
90    a. In this vale of tears, some tweaking may be unavoidably required
91       when making software run on more than one machine. But we should
92       try to minimize it, not embrace it. And to the extent that it's
93       unavoidable, where possible it should be handled by making an 
94       abstract value or operation which is used on all systems, then
95       making separate implementations of those values and operations
96       for the various systems. (This is very analogous to object-oriented
97       programming, and is good for the same reasons that method dispatch
98       is better than a bunch of CASE statements.)
99 4. making a better programming environment
100    a. Declarations *are* assertions! (For function return values, too!)
101    b. Making the debugger, the profiler, and TRACE work better.
102    c. Making extensions more comprehensible.
103       i. Making a smaller set of core extensions. IMHO the high level
104          ones like ONCE-ONLY and LETF belong in a portable library
105          somewhere, not in the core system.
106       ii. Making more-orthogonal extensions. (e.g. removing the
107           PURIFY option from SAVE-LISP-AND-DIE, on the theory that
108           you can always call PURIFY yourself if you like)
109       iii. If an extension must be complicated, if possible make the
110            complexity conform to some existing standard. (E.g. if SBCL
111            supplied a command-line argument parsing facility, I'd want
112            it to be as much like existing command-line parsing utilities
113            as possible.)
114 5. other nice things
115    a. improving compiled code
116       i. faster CLOS
117       ii. bigger heap
118       iii. better compiler optimizations
119       iv. DYNAMIC-EXTENT
120    b. increasing the performance of the system
121       i. better GC
122       ii. improved ability to compile prototype programs fast, even 
123           at the expense of performance of the compiled program
124    c. improving safety
125       i. more graceful handling of stack overflow and memory exhaustion
126       ii. improving interrupt safety by e.g. locking symbol tables
127    d. decreasing the size of the SBCL executable
128    e. not breaking old extensions which are likely to make it into the
129       new ANSI standard
130 6. other maybe not-so-nice things
131    a. adding whizzy new features which make it harder to maintain core 
132       code. (Support for the debugger is important enough that I'll 
133       cheerfully make an exception. Multithreading might also be
134       sufficiently important that it's probably worth making an exception.)
135       The one other class of extensions that I am particularly interested
136       is CORBA or other standard interface support, so that programs can
137       more easily break out of the Lisp/GC box to do things like graphics.
138       ("So why did you drop all the socket support, Bill?" I hear you
139       ask. Fundamentally, because I have 'way too much to maintain
140       already; but also because I think it's too low-level to add much
141       value. People who are prepared to work at that level of abstraction
142       and non-portability could just code their own wrapper layer
143       in C and talk to it through the ALIEN stuff.)
144 7. judgment calls
145    a. Sharp, rigid tools are safer than dull or floppy tools. I'm
146       inclined to avoid complicated defaulting behavior (e.g. trying
147       to decide what file to LOAD when extension is not specified) or
148       continuable errors, preferring functions which have simple behavior
149       with no surprises (even surprises which are arguably pleasant).
151 CMU CL maintenance has been conservative in ways that I would prefer to 
152 be flexible, and flexible in ways that I'd prefer to be conservative.
153 CMU CL maintainers have been conservative about keeping old code and
154 maintaining the old structure, and flexible about allowing a bunch of 
155 additional stuff to be tacked onto the old structure.
157 There are some good things about the way that CMU CL has been
158 maintained that I nonetheless propose to jettison. In particular,
159 binary compatibility between releases. This is a very handy feature,
160 but it's a pain to maintain. At least for a while, I intend to just
161 require that programs be recompiled any time they're to be used with a
162 new version of the system. After a while things might settle down to
163 where recompiles will only be required for new major releases, so
164 either all 3.3.x fasl files will work with any 3.3.y runtime, or all
165 3.w.x fasl files will work with any 3.y.z runtime. But before trying
166 to achieve that kind of stability, I think it's more important to 
167 be able to clean up things about the internal structure of the system.
168 Aiming for that kind of stability would impair our ability to make 
169 changes like
170   * cleaning up DEFUN and DEFMACRO to use EVAL-WHEN instead of IR1 magic;
171   * reducing the separation between PCL classes and COMMON-LISP classes;
172   * fixing bad FOPs (e.g. the CMU CL fops which interact with the *PACKAGE*
173     variable)