Subject: Re: Standards compliance question
From: rpw3@rpw3.org (Rob Warnock)
Date: Thu, 20 Mar 2003 06:14:59 -0600
Newsgroups: comp.lang.lisp
Message-ID: <ee6dnW9hXeNeLeSjXTWc-w@speakeasy.net>
Steven M. Haflich <smh_no_spiced_ham@alum.mit.edu> wrote:
+---------------
| Even though you think you know what is required from the language,
| and what is prohibited, the cracks are many and wide.
| 
| What does your favorite conforming implementation do with the following:
| 
| (make-package (copy-seq "FOO"))
| (setf (aref (package-name (find-package "FOO")) 2) #\B)
| (find-package "FOB)
| 
| I can find no prohibition in the ANS against executing this sequence,
| and if I were sufficiently ignorant of both common practice and
| implementation, I might expect it to work.
+---------------

Yes, but if one had hung out here in c.l.l. and seen the number of
catcalls about modifying constants [yes, yes, even though you explicitly
made a mutable copy of "FOO" in this case] one might hesitate a moment
about trying to do anything quite so "under-the-covers". *I* certainly
got a uneasy feeling about it, and I'm relatively new to CL (though not
to Scheme or its implementation).

For example, it seems reasonable to me for an implementation to use
a hash table internally to map package names to packages, and we *do*
have a restriction [CLHS 18.1.2] against modifying hash table keys!
[Also see CLHS 18.1.2.2.2.]

Plus, it says under Functions INTERN and MAKE-SYMBOL and Class SYMBOL,

	Once a string has been given as the name argument to MAKE-SYMBOL
	[or to INTERN, in the situation where a new symbol is created],
	the consequences are undefined if a subsequent attempt is made
	to alter that string. 
and:
	Every symbol has a name, and the consequences are undefined if
	that name is altered.

Packages seem to me to be enough like symbols to cause one to be at least
a little bit hesitant about risking mutating their names, either. Enough
that one might have ask, "Well, how *should* I think about doing this?"
One might look again at the spec [as I did] and find that in the case of
packages there's a way which *is* explicitly sanctioned:

        (make-package (copy-seq "FOO"))  ==>  #<PACKAGE FOO>

        (let* ((package (find-package "FOO"))
               (new-name (copy-seq (package-name package))))
          (setf (aref new-name 2) #\B)
          (rename-package package new-name))  ==>  #<PACKAGE FOB>

        (find-package "FOB")  ==>  #<PACKAGE FOB>


-Rob

-----
Rob Warnock, PP-ASEL-IA		<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607