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

need for export controls

I was rather incoherent last night.  The scenario where a problem occurs
because a symbol is exported that shouldn't have been, perhaps because
of a mistake in a declare-package, is as follows:

Package A is use-package'd by packages B and C.
The programs in B and C each use a symbol BLORPH, knowing it
to be internal.  Let's say they use it as an indicator to put
on property lists.
A gets a new external, BLORPH, that it didn't have before.
Perhaps this is for real, or perhaps it's just a typo for BLEAGH.
If this external is added after B and C have already been loaded
and have each interned their own BLORPH, you get a name clash error
(even if only one of B and C have been loaded).
If this external is added when neither B nor C has been loaded yet,
when they do get loaded and make their BLORPH, they both get the
same symbol.  If they can ever get "near each other," e.g. they both
try to put BLORPH properties on the same symbol, you have an undetected
name clash.

Morals of the story:

If you want to be very conservative, use SHADOW on all symbols that
you use as unique, private identifiers, rather than simply making the
(usually correct) assumption that you won't inherit anything by the name.

There are two kinds of externals: the kind that are only accessed via
qualified names, which are safe from undetected name clashes, and the
kind that are accessed via use-package or include-package.  Every new
external of the latter kind must be accompanied by documentation when
released to the world.

As a third style (besides qualified names and wholesale use-package),
B and C could have IMPORTed just the symbols they actually wanted from A.
I don't think Common Lisp can legislate any of these three styles out
of existence, though; consider the LISP package, which it would be
silly to access in any but the "use" style.

The name clash detection I am promoting will detect all clashes in the
qualified name style (where it becomes ambiguous what a certain qualified
name refers to), clashes in the import style where you accidentally
referenced a name before you imported it and hence got an internal symbol,
and clashes in the use style caused by modifying a package after someone
has already inherited it.  It cannot detect clashes in the import style
where "the left hand doesn't know what the right hand is doing," i.e. two
parts of a program in a single package don't agree about whether a certain
name is to be private or imported.  In general it cannot detect name
clashes among the denizens of a single package!  It cannot detect clashes
in the use style where a new symbol, unanticipated by the inheriting
programs, is exported by the ancestor program -before- the inheriting
programs are loaded.  This one I think is inherent in the nature of
packages, or in the nature of contracts, and cannot be solved.

It would be very nice if the Common Lisp manual, at least in the second
edition, does not make the mistake we made in the Lisp machine manual and
omit all discussion of these issues, on the grounds that it would scare
the users or that it would make the manual too big.  It's important to
have a clear exposition of what the problems with packages are.  Maybe
I should just write (with help from others, surely) a freestanding paper
on the subject.