[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

package.mss.108



I am almost completely happy with this.  There is one big problem, one
medium-sized problem, and a few small problems.

Small:

Does the list returned by package-nicknames include the primary name?
Say explicitly.

find-all-symbols has to accept a string as an argument so that one
doesn't spuriously create a symbol just to use as an argument.  I
suppose one could use an uninterned symbol, but it seems better to me
to make it accept either a string or a symbol, or else just a string.
The string of course has to be in the same case as a symbol's print-name;
case-dependent lookup is used.

There are several typographical errors in the description of do-symbols.

Add do-external-symbols

EXPORT and related functions should take an optional second argument which
is the package to operate on, or its name, defaulting to *PACKAGE*.  This
is mainly valuable when you have a module that presents multiple interfaces
and hence has some "extra" packages associated with it; the external
symbols of each package correspond to one interface to that module.  The
code is all loaded into one package, but different things are exported to
different packages; some symbols are present in more than one interface and
hence exported to more than one package.

Medium:

I'm not completely happy with declare-package and the :export keyword.  I
don't like the idea of package A exporting symbols from package B; what if
there is a typographical error, a conceptual mistake, or an obsolete symbol
in the list supplied by package A, which is a duplicate of package B's
list?  I'd like to see some error-checking here.  I suggest that there be
some distinction between declare-package done by the "owner" of the package
vs. declare-package done by some "user" of the package, and a consistency
check between them (what is exported by a user is a subset of what is
exported by the owner, and likewise for what is include-package'd).
Possibly declare-package should be the "user" function, make-package should
be the "owner" function, and make-package should err if the package has
been made already but not if it has been declared already.  in-package
properly should be a variant of make-package, not of declare-package, in
this scenario.  However it is desirable to be able to go "into" a package
more than once; I suggest that perhaps it is wrong for in-package to do an
implicit make, and the make should be done separately.

Large:

The statement "No two symbols in the same package may have the same name"
is not enlarged upon, and furthermore since this doesn't use the
accessible/present terminology that was just defined, it isn't clear which
is meant.

To me, it is clear that the package consistency rules require that no two
symbols -accessible- from the same package have the same name, unless one
has been explicitly shadowed.  Allowing implicit shadowing makes the
result (which of the two symbols is actually accessible) dependent
upon the order in which the symbols were first seen, or on the order
that use-package and include-package put things onto lists, and destroys
read-read consistency.

In your writeup, name clashes are only discussed under IMPORT.  Name
clashes should be given their own discussion section, and the following
functions should be required to check for name clashes: EXPORT, IMPORT,
USE-PACKAGE, INCLUDE-PACKAGE, and the implicit calls to those functions
from MAKE-PACKAGE, DECLARE-PACKAGE, and IN-PACKAGE.  When the externals of
a package are altered, the check for name clashes must extend to all
packages that inherit from that package (via either use or include).  A
name clash occurs when there is an attempt to make a symbol accessible in a
package with the same name as a distinct symbol already accessible in that
package, except when shadowing has been used to declare the user's
intentions (there is a symbol already accessible in the package, with
the same name, that was mentioned by SHADOW).  When a name clash occurs,
a correctable error is signalled.  A variety of ways to continue from
the error may be provided by an implementation, including such possibilities
as declining to perform the invalid operation, uninterning or unexporting
the other symbol, automatically shadowing, and (in some implementations)
linking function and value cells to make the two clashing symbols equivalent
for those uses of symbols (but not equivalent for EQ of course) and
uninterning one of them.  It may also prove desirable in practice to
have variables that can be set to cause automatic continuation from
name clashes; but we shouldn't standardize on those yet.