[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
packages, yet again
- To: common-lisp@su-ai
- Subject: packages, yet again
- From: David A. Moon <Moon%SCRC-TENEX%MIT-MC@SU-DSN>
- Date: Tue, 17 May 1983 00:51:00 -0000
- In-reply-to: The message of 16 May 83 00:48-EDT from Scott E. Fahlman <Fahlman at CMU-CS-C>
I am quite happy with this version of the package proposal. There are
still some minor nits to pick:
It doesn't say explicitly what happens if MAKE-PACKAGE is done twice with
the same name. Is this an error? Is it an error for IN-PACKAGE, too? Is
there any attempt to detect two people independently choosing the same package
name, or is that expliclitly considered impractical to detect? I'd suggest
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).
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.
Say somewhere that the accessor function for the home package of a symbol
is SYMBOL-PACKAGE.
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
implicitly.
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.
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
itself.
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.
Why do two of the modules in Newton's init file have ".lsp" in their names?