Subject: Re: destroying CLOS objects
From: Erik Naggum <erik@naggum.net>
Date: 2000/10/11
Newsgroups: comp.lang.lisp
Message-ID: <3180295081209554@naggum.net>

* Tunc Simsek <simsek@robotics.eecs.berkeley.edu>
| I have a question regarding CLOS objects created with make-instance.
| Is it possible in any way to 'destroy' such an object.  For example,
| to say (delete-instance ...) or such that would effectively make
| that object disappear in a meaningful way (for example, all
| references to that object will refer to nil)

  I'll assume that you're _not_ an idiot and that it is inappropriate
  to answer your question with "you don't need this because we have a
  garbage collector in Common Lisp" as if you didn't know that.

  The problem you allude to is that of tracking down all references.
  This can't be done, so forget it.  (If you think it can, you didn't
  consider the value of "all" carefully enough, unless you actually
  are the garbage collector, but that's not what you're asking about.)

  So we don't track down any references at all.  Instead, we make the
  perfectly valid references we already have around the system point
  to the same object, but make it a different kind of object.  You can
  do that with change-class.  Except you can't turn a CLOS object into
  a system object like nil, but if all you're interested in is junking
  a bunch of data that otherwise would hang around forever because
  there might be some dangling reference somewhere you didn't think
  of, create some very empty class, (defclass nothingness () ()), and
  change instances into that class.

  Then there's the extremely valuable slot-makunbound which makes any
  references to slots of CLOS instances signal an error (or call the
  handler, to be more precise, which generally signals an error) unles
  sit has been bound anew.  This guarantees that you won't have any
  rogue referents at all.  However, this requires that you destroy
  objects that are tied to particular slots.  I find that this is
  often the case, but your mileage may vary.

| A second question (a follow-up on an earlier post) is regarding
| side-effects.  I've decided to make a package (say :foo) that
| has interned only what I believe to be side-effect free functions.
| Is there someway that I can ensure a form in, say package :goo,
| to use only those functions:
| 
| (let ((*package* (find-package 'foo)))
|    ... stuff ...
|     ))
| 
| in stuff use of :: should not be allowed, for example.

  This requires access to internals, and is generally not simple to
  accomplish, because intern is such a basic function.  However, if
  you are a supported Allegro CL user and promise not to use Presto,
  you can take a look at src:code;package.cl and locate intern*, then
  remove the #+notyet, and compile that one function.  After this fix,
  you get results like these:

(13) cl-user
(handler-case (intern "foobarzot" :cl)
  (excl:package-locked-error ()
    (format *debug-io* "~&~s: no can do.~%" '(intern "foobarzot" :cl))))
(intern "foobarzot" :cl): no can do.
=> nil

  The macro excl::without-package-locks allows its body forms to make
  changes to locked packages.

#:Erik
-- 
  I agree with everything you say, but I would
  attack to death your right to say it.
				-- Tom Stoppard