[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Printer bug
It is sometimes useful to have a package that does not use the LISP
package. Suppose we have such a package and also that it neither has a
local symbol named "NIL" nor imports one from another package. If our
package is the current package, and we cause LISP:NIL to be printed, it
should print as "LISP:NIL" in order to maintain print-read consistency.
However, it actually prints as "NIL". But then, if we create a local
symbol named "NIL, LISP:NIL prints as "LISP:NIL". (See example below.)
I suspect the problem is due to the following line in "c/print.d":
else if (PRINTpackage||find_symbol(x,current_package())!=x) {
<code to print package prefix>}
PRINTpackage (ie, SI:*PRINT-PACKAGE*) is usually false. The call to
find_symbol is supposed to check whether the print name alone is enough
to get back the same symbol or whether it gets a different symbol (so
that the package is needed to get the right one). The expression
find_symbol(x,current_package())!=x
is supposed to be true when the package prefix is needed.
Now Suppose x is the symbol LISP:NIL and that _no_ symbol is found by
find_symbol. (This is the case described in the 1st paragraph above.)
The value of expression should be true to show that a package prefix is
needed. However, it will actually be false, because because find_symbol
returns LISP:NIL when a symbol isn't found. So the package prefix won't
be printed. However, if there were a local symbol named "NIL", everything
would work as it was intended to.
Another strange things about this code is that, unlike the Lisp-level
version of the function, this find_symbol can be called with either a
symbol or a string as it's argument. Moreover, this works not because
find_symbol checks and uses the print name if given a symbol but because
symbol structs have enough of the same layout as string structs so that
enough of the operations on strings will work. Humm.
Here's a demonstration:
------------------------------
I happen to be using this KCL:
AKCL (Austin Kyoto Common Lisp) Version(1.457) Wed Feb 21 19:43:35 GMT 1990
Contains Enhancements by W. Schelter
Changes in version 1-455 definitely require recompilation of user files.
Get in a package that doesn't use the LISP package
>(in-package :a :use '())
#<"A" package>
Check that it doesn't use it.
A>(lisp:package-use-list lisp:*package*)
NIL
See how () prints.
A>'()
NIL
This is wrong. It should be "LISP:NIL".
A>(lisp:= 1 2)
NIL
Still wrong. Now create a symbol named "NIL" in the current package.
A>'nil
NIL
See how () prints now.
A>'()
LISP:NIL
Now it's right.
A>(lisp:= 1 2)
LISP:NIL
Here too.
------------------------------
Jeff Dalton, JANET: J.Dalton@uk.ac.ed
AI Applications Institute, ARPA: J.Dalton%uk.ac.ed@nsfnet-relay.ac.uk
Edinburgh University. UUCP: ...!ukc!ed.ac.uk!J.Dalton