[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"))
  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
    *PACKAGE* can't be a deleted package:
      *PACKAGE* has been reset to #<PACKAGE "COMMON-LISP-USER">.

COMPILE-FILE does something like
(let ((*package* *package*))
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.


[*] 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