[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
What does LOAD use for read table & package?
- To: common-lisp@SU-AI.ARPA
- Subject: What does LOAD use for read table & package?
- From: David A. Moon <Moon@SCRC-STONY-BROOK.ARPA>
- Date: Fri, 28 Feb 86 14:24 EST
- In-reply-to: <FAHLMAN.12186830790.BABYL@C.CS.CMU.EDU>
Date: Thu, 27 Feb 1986 20:40 EST
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
I believe that the only viable possibility for LOAD of a compiled file
is to bind *PACKAGE* to the same value that it had when the file was
compiled. This means that the compiler must transmit this information
to the loader in some way. If there are SETQs of *PACKAGE* in the
source file (perhaps disguised as IN-PACKAGE), then they should do the
same thing at load time as they did at compile time.
For those of us who want to learn from your experience, could you
elaborate a bit on the above pronouncement? Why is it a good idea to
bind *PACKAGE* to the compile-time value, rather than using what is
current at load time?
The READ operations that the compiler does lose information about what package
prefixes were specified on symbols. The compiler has to put something in its
output file that expresses the identity of those symbols, and the loader has to
take that information in the file and reproduce the same symbols. (Perhaps
I should stop here and ask if you agree that the desired semantics is for loading
the compiled file to refer to the same symbols as loading the source file.)
In my experience, the way that produces the least surprise for users is for the
compiler to record symbols in its output file using the same algorithm as PRINT
to decide when to put a package prefix, and for the loader to use the same
algorithm as READ to interpret those prefixes, relative to the same package with
respect to which they were printed. We have tried other techniques, such as
always putting a package prefix in the compiler's output file, and found them
deficient. The problem with always putting a package prefix is that almost any
change to the package structure (what symbol is exported from where, or what is
the home package of a symbol that is in multiple packages) will prevent the
compiled file from loading correctly.
We do have a way to force LOAD to load into a different package than the
one the file was compiled in, using a :PACKAGE keyword argument, but in
practice this is rarely used.
What if the compile-time package doesn't exist at load time?
Then the program doesn't load. I don't see this as any different from calling
a function that doesn't exist at load time. I also don't see this as surprising,
since in my view the compile-time package is very much part of the program, not
an accidental detail of compilation, and it would be unusual for it not to exist
at load time. Of course any mechanism, such as IN-PACKAGE or -*-, that tells the
compiler to create the package if it does not already exist should be transmitted
to the loader, which should also create the package if it does not already exist.
This is of course only a tiny part of the whole issue of compilation and
environments. I think it very unlikely that we will be able to agree on
full details of programming environments, since Common Lisp is being
implemented on such a wide range of systems with different capabilities
and different goals. In fact such agreement would be undesirable in my
view, since it would either exclude a large sector of the Common Lisp
community or would require a least-common-denominator programming
environment that would be of little use to those among my users who are
tackling extremely ambitious projects in Lisp. I agree with what you
said in another message that the important thing is to focus on what is
necessary to write portable programs.