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