Three portability issues are discussed. The first, the superset problem, describes some difficulties
in porting "pure" COMMON LISP code into an implementation that supports extensions.
Specifically, problems arising from the implementation of packages and system macros by a superset
environment are discussed. The second issue, the problem of top-level forms, concerns
an implicit distinction between LISP code contained inside the definition of some named form
(e.g., defun) and code appearing in a "top-level" context in a file. The distinction is necessary
in order for utilities that use read to parse text into code (e.g., XREF, compilers, and language-specific
editors). It is also found to be the source of semantic ambiguities arising from the use
of eval-when by application programs. It is likewise related to the third issue, compiler side efects,
where the ambiguity involves how a series of LISP forms are processed by the compiler
(or XREF) so that the side effects of certain forms, such as macro definitions, can be used in the
processing of later forms, such as macro calls, and how these side effects are related to the state
of the current LISP environment. While these issues arose in the context of a program analysis
utility, they reveal potential problems for portability of arbitrary COMMON LISP programs,
because the position taken by an implementation will prescribe how a portable program should
be organized. Specific recommendations are given for writing portable code in light of these
issues. But first, a brief description of XREF is in order.
2 The XREF Cross Reference Utility
XREF is a program analyzer for COMMON LISP programs that is used primarily as a cross
reference tool. It is similar in function to the MASTERSCOPE facility of INTERLISP[2]. XREF
analyzes code much like a compiler or interpreter. It parses text (program source) into s-expression
forms and recursively traverses them, simulating the COMMON LISP lexical and
dynamic binding environments for functions, macros, and variables. It analyzes each form,
expanding macros and interpreting special forms, and records the interrelationships among
these entities. It stores these relationships in a memory-resident or file-resident database, and
uses the database to generate reports on source files or named forms. For example, a report on
a program source file lists several types of interdependencies: which named forms (functions,
macros, special variables) are defined (proclaimed) internally in the file, what other forms
explicitly call (evaluate, bind, assign to) internal forms and what forms are called by internal
forms, the {iles where these external forms are defined, and so on.
XREF has been running in the Digital Equipment Corporation implementation of COMMON
LISP since early 1984, and the sources are supplied with the VAX LISP product.2 It has been used
successfully in the development and maintenance of a variety of medium and large programs.
It only requires one implementation-dependent function: proclaimed-specia1-by-system?,
which tells whether a symbol has been declared to always name a special variable (by the
function proclaim). nbsp;3
Some implementation-dependent features of XREF, like error handling,
are useful but not essential to analyzing "correct" COMMON LISP programs}
4
*****************
2
VAX LISP is a registered trademark of Digital Equipment Corporation. VAX LISP is described in [3].
3
Most implementations use a simple mechanism, like a property list entry, to record this fact. It is necessary
that XREF ask the system about this property because proclamations have dynamic extent and thus a symbol
may have been proclaimed special outside of code that XREF has seen.
4
Portable alternatives are provided using read-time conditionals (#+ and #-) to distinguish them in the code.
|