[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Conservation of nits
- To: David A. Moon <Moon%SCRC-TENEX%MIT-MC@SU-DSN>
- Subject: Conservation of nits
- From: Scott E. Fahlman <Fahlman@CMU-CS-C>
- Date: Wed, 18 May 1983 04:08:00 -0000
- Cc: common-lisp@su-ai
- In-reply-to: Msg of 16 May 1983 20:51-EDT from David A. Moon <Moon%SCRC-TENEX%MIT-MC at SU-DSN>
Fahlman's Law of Package Systems: Nits can neither be created nor
destroyed. It is occasionally possible to smash big ones into a whole
lot of little ones.
that duplicate package name be an error for MAKE-PACKAGE, a primitive, but
not for IN-PACKAGE, since you'd like to be able to load a program twice
(presumably after changing it to fix something).
OK. That's the way I had it originally, before our go-round about
IN-PACKAGE augmenting the externals of the package in question.
I hope you realize that IN-PACKAGE is incompatible with incremental
re-compilation of portions of files (after editing them), a Lisp machine
productivity feature that users are uniformly enthusiastic about. I
would think that this would be something that Spice Lisp would definitely
want, too, once you have a compiler that runs natively in your Lisp.
I'm not sure yet whether we will strongly discourage people from using
IN-PACKAGE, or whether we will provide a kludgey way for the editor to
know that it must parse the beginning of the file looking for IN-PACKAGE
in order to determine in what package to read forms from the file.
I don't completely understand this. I looked for incremental
compilation in the Confederate edition of the Chine Nual and couldn't
find anything about it. What exactly do you folks do? I would have
assumed that if you do incremental re-compilation on an ASCII file, you
take some notice of the -*-Package:foo-*- business, no? IN-PACKAGE
would have the same set of problems as that. I would hate to have you
tell users not to use IN-PACKAGE. Do you have a specific proposal?
Say somewhere that the accessor function for the home package of a symbol
It isn't clear from the description whether SHADOWING-IMPORT will call
UNINTERN if the symbol being shadowed is directly in the package (rather
than inherited with USE-PACKAGE). Surely this must be what was intended.
Also SHADOWING-IMPORT should be in the list of functions that should be
used at top level.
The writeup doesn't say why certain functions should be used at top
level. One reason is that if changes are being made to *package* with
the expectation that they will affect how forms later in the file are
read, then those changes had better happen at compile time before
further forms are read from the file. The other reason is that in many
implementations the output from the compiler is designed so that the
loader can look symbols up once, rather having to call INTERN every time
a symbol is referenced. This means that the compiler must know when the
package state is changing (i.e. the read-read consistency rule doesn't
apply). It would probably be best to include an Implementation Note
pointing out the restrictions this places on the compiler/loader
implementation: the compiler may not read the whole file before compiling
any of it (as the Lisp machine used to do in order to improve virtual
memory locality); the loader may not do all its INTERNs before evaling
any of the top-level forms (as Multics Maclisp does).
The writeup should say explicitly which functions get an automatic
(eval-when (compile) ...) wrapped around them when they are seen at
top level by the compiler. The example at the end is assuming this
Well, both of the above comments assume that the compiler represents
symbols and their packages internally just by reading them into the
right package. Certainly the compiler has to keep track of what
packages the various symbols want to end up in, but this might be done
by some more complex mechanism if the compiler wanted to keep its guts
somewhat separate from the stuff it is reading. I'll see if I can say
something sufficient about this without over-specifying the mechanism.
I can find no justification in the previous discussion for the suddenly
introduced restriction that EXPORT and UNEXPORT are not allowed in
packages that have been USE-PACKAGE'd, unless this is a Solomonian
attempt to resolve the copy vs reference issue. If this is trying to
deal with the case of exporting a symbol too late, after someone who
thought they were getting it via USE-PACKAGE made an internal symbol
instead, the naming conflict checks I suggested earlier detect this and
are able to tell you exactly what happened. If this is trying to deal
with the case where exporting a new symbol, that people using
USE-PACKAGE didn't expect to see exported, causes what was expected to
be two distinct symbols, internal in different packages, to become one
(external) symbol, it doesn't deal with it. That can just as well
happen if all the EXPORTs are done before all the USE-PACKAGEs, and is
basically indetectable. This screw case is really a lot like someone
changing what a function does without telling everyone who uses it.
I was just trying to do something simple and safe that might end the
debate. I figured that I could get this "package locking" rule right on
the first try, and that some tricky rule to signal an error only in the
case of a conflict with some symbol in the inferior package that is not
on that package's shadow list would lead to N more rounds of revision.
You seem to understand this better than I do. How about if you propose
the exact wording for the error-checking rule you would like to see here
(both for EXPORT and for UNEXPORT)? That would be the quickest way to
converge, I think.
The writeup says that SHADOW and SHADOWING-IMPORT "can produce confusing
situations that violate the consistency rules." This is misleading.
They are a change of package state, just like setting *PACKAGE*, so there
isn't consistency between the world before calling SHADOW and the world
after calling it. But the world after calling SHADOW is consistent with
OK, good point, sloppy wording.
The &optional package argument to USE-PACKAGE and UNUSE-PACKAGE is missing.
Why does it say init files are not usually compiled? This is a
non-sequitur where it appears, and also is untrue in some
implementations, ours for instance.
Weinreb and Greenberg sent me a message pointing out that Newton's init
file would not work if compiled, and that it needed some (eval-when
(compile ..)) stuff added. Since this was supposed to the simple part
of the example (the sort of interaction that naive users might have with
the package system), I didn't want to hair it up that way, so I just
mentioned that you don't want to compile these things. Actually, I
guess with the recent changes, and if we put in the comment about
implicit EVAL-WHENs, we don't need to worry about this.
Just out of curiosity, why in the world would anyone compile an INIT
Why do two of the modules in Newton's init file have ".lsp" in their names?
I'll try to get this fixed up tomorrow.