[slime-devel] New to lisp and slime
Helmut Eller
heller at common-lisp.net
Sat Apr 2 07:58:13 UTC 2011
* Paul Bowyer [2011-04-01 16:23] writes:
>> In my learning exercises, I have been using something like:
>> -----------------------------------------------------------------------------
>> (eval-when (:compile-toplevel :load-toplevel :execute)
>> (if (find-package "CH16")
>> (delete-package "CH16"))
>> )
>> (defpackage "CH16"
>> (:use "COMMON-LISP" "UTIL")
>> (:shadow "LENGTH" "MEMBER" "COUNT")
>> (:export "LENGTH" "MEMBER" "BEFORE"
>> "NUMBER-LISTP" "SAME-LENGTH1"
>> "SAME-LENGTH2" "COUNT")
>> )
>>
>> (in-package "CH16")
I think the problem is that the code tries to delete the current
package, i.e. the package stored in the variable *package*. You can
also produce the error in a normal SBCL session without Slime:
cl-user> (load (compile-file "x.lisp"))
[...]
t
cl-user> (in-package ch16)
#<package "CH16">
ch16> (load (compile-file "x.lisp"))
[...]
debugger invoked on a SIMPLE-TYPE-ERROR in thread #<THREAD
"initial thread" RUNNING
{AA43859}>:
*PACKAGE* can't be a deleted package:
*PACKAGE* has been reset to #<PACKAGE "COMMON-LISP-USER">.
[...]
COMPILE-FILE does something like
(let ((*package* *package*))
<code-that-does-the-rest>)
so that *package* is automatically reset to the original value at the
end. But if *package* is the CH16 package before you call COMPILE-FILE
and that CH16 package is deleted at compile-time, we end up with a
deleted package in *package*.
Now, you may ask why *package* is CH16 when using Slime. That's because
there is a (in-package ch16) form in the file and Slime tries to be
friendly and automatically switches to that package.
Yes, this is really confusing.
CLTL2[*] has some good rules to avoid many of those situations:
In order to guarantee that compiled files can be loaded correctly, the
user must ensure that the packages referenced in the file are defined
consistently at compile and load time. Conforming Common Lisp programs
must satisfy the following requirements.
- The value of *package* when a top-level form in the file is
processed by compile-file must be the same as the value of *package*
when the code corresponding to that top-level form in the compiled
file is executed by the loader. In particular, any top-level form in
a file that alters the value of *package* must change it to a
package of the same name at both compile and load time; moreover, if
the first non-atomic top-level form in the file is not a call to
in-package, then the value of *package* at the time load is called
must be a package with the same name as the package that was the
value of *package* at the time compile-file was called.
- For every symbol appearing lexically within a top-level form that
was accessible in the package that was the value of *package* during
processing of that top-level form at compile time, but whose home
package was another package, at load time there must be a symbol
with the same name that is accessible in both the load-time
*package* and in the package with the same name as the compile-time
home package.
- For every symbol in the compiled file that was an external symbol in
its home package at compile time, there must be a symbol with the
same name that is an external symbol in the package with the same
name at load time.
Some of the package related functions like delete-package, unintern,
rename-package etc. can lead to those confusing situations. If
possible, create the package structure once and don't modify it later.
Obviously that's not always possible but now you know that you need to
be careful when messing around with packages.
Helmut
[*] http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/html/cltl/clm/node224.html#SECTION002910000000000000000
More information about the slime-devel
mailing list