From: Damien Kick
Subject: Removing types
Date: 
Message-ID: <pt2dxqih.fsf@email.mot.com>
In an old post in response to a question about removing the effects of
creating a new type with DEFSTRUCT, Kent Pitman mentions the use of
UNINTERN
<http://groups.google.com/groups?hl=en&lr=&selm=sfwu1zj9a49.fsf%40world.std.com&rnum=4>:

    The easiest way is to give him different packages each time, and
    make sure all your INTERN's are done relative to his user package.
    Then you can DELETE-PACKAGE to start over (or just make a new
    package, keeping both environments available in case he wants to
    go back) or you can edit out certain symbols with UNINTERN without
    it potentially affecting your own programs.

I'm interpretting the above to mean that if one UNINTERNs the symbol
that names a type created by either DEFSTRUCT, DEFCLASS, or DEFTYPE,
or uses DELETE-PACKAGE as something of a heavy handed UNINTERN, that
this will also effectively remove the type that it named.  However, I
can't seem to find anything in the CLHS that supports my
interpretation.  Am I understanding Kent correctly?

From: Paul F. Dietz
Subject: Re: Removing types
Date: 
Message-ID: <VZOdnZCHNb6sOAfcRVn-sQ@dls.net>
Damien Kick wrote:

> I'm interpretting the above to mean that if one UNINTERNs the symbol
> that names a type created by either DEFSTRUCT, DEFCLASS, or DEFTYPE,
> or uses DELETE-PACKAGE as something of a heavy handed UNINTERN, that
> this will also effectively remove the type that it named.  However, I
> can't seem to find anything in the CLHS that supports my
> interpretation.  Am I understanding Kent correctly?

If you remove all access to the symbol naming the type, you have,
in effect, removed the type, since its presence or absence can no
longer have any observable effect on a conforming program.

	Paul
From: Barry Margolin
Subject: Re: Removing types
Date: 
Message-ID: <barmar-7B997D.23333216112004@comcast.dca.giganews.com>
In article <······················@dls.net>,
 "Paul F. Dietz" <·····@dls.net> wrote:

> Damien Kick wrote:
> 
> > I'm interpretting the above to mean that if one UNINTERNs the symbol
> > that names a type created by either DEFSTRUCT, DEFCLASS, or DEFTYPE,
> > or uses DELETE-PACKAGE as something of a heavy handed UNINTERN, that
> > this will also effectively remove the type that it named.  However, I
> > can't seem to find anything in the CLHS that supports my
> > interpretation.  Am I understanding Kent correctly?
> 
> If you remove all access to the symbol naming the type, you have,
> in effect, removed the type, since its presence or absence can no
> longer have any observable effect on a conforming program.

But if you still have any objects of that type, they have to have 
back-references to the type name for TYPE-OF to work.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Paul F. Dietz
Subject: Re: Removing types
Date: 
Message-ID: <8a6dnQ1DSI4D1QbcRVn-1Q@dls.net>
Barry Margolin wrote:

>>If you remove all access to the symbol naming the type, you have,
>>in effect, removed the type, since its presence or absence can no
>>longer have any observable effect on a conforming program.
> 
> 
> But if you still have any objects of that type, they have to have 
> back-references to the type name for TYPE-OF to work.

But then you still have access to the symbol, albeit not via the package.

You can get rid of the type name by setf of the CLASS-NAME accessor.

	Paul

[ I wonder what TYPE-OF returns if the class of an object has no name?
(write test, applies to a CL implementation) ... New tests coming! ]
From: Barry Margolin
Subject: Re: Removing types
Date: 
Message-ID: <barmar-B8BDBA.21040217112004@comcast.dca.giganews.com>
In article <······················@dls.net>,
 "Paul F. Dietz" <·····@dls.net> wrote:

> Barry Margolin wrote:
> 
> >>If you remove all access to the symbol naming the type, you have,
> >>in effect, removed the type, since its presence or absence can no
> >>longer have any observable effect on a conforming program.
> > 
> > 
> > But if you still have any objects of that type, they have to have 
> > back-references to the type name for TYPE-OF to work.
> 
> But then you still have access to the symbol, albeit not via the package.
> 
> You can get rid of the type name by setf of the CLASS-NAME accessor.

That won't necessarily work for types defined with DEFSTRUCT.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Tim Bradshaw
Subject: Re: Removing types
Date: 
Message-ID: <1100689338.121170.12440@f14g2000cwb.googlegroups.com>
Paul F. Dietz wrote:
>
> If you remove all access to the symbol naming the type, you have,
> in effect, removed the type, since its presence or absence can no
> longer have any observable effect on a conforming program.
>

Only in the absense of any objects of that type.  I think you also
need to remove access to symbols naming direct or indirect subtypes as
well, and any objects of those types.  And even then, only in the
absense of many kinds of MOP, which is obviouly implied by
`conforming' in your message, but since most implementations do have
some MOP functionality, I think this is not going to be true in
practice.

--tim
From: james anderson
Subject: Re: Removing types
Date: 
Message-ID: <d21f61e3.0411170311.453d27c1@posting.google.com>
"Paul F. Dietz" <·····@dls.net> wrote in message news:<······················@dls.net>...
> Damien Kick wrote:
> 
> > I'm interpretting the above to mean that if one UNINTERNs the symbol
> > that names a type created by either DEFSTRUCT, DEFCLASS, or DEFTYPE,
> > or uses DELETE-PACKAGE as something of a heavy handed UNINTERN, that
> > this will also effectively remove the type that it named.  However, I
> > can't seem to find anything in the CLHS that supports my
> > interpretation.  Am I understanding Kent correctly?
> 
> If you remove all access to the symbol naming the type, you have,
> in effect, removed the type, since its presence or absence can no
> longer have any observable effect on a conforming program.
> 
> 	Paul

as the only effect of delete-package on any symbols which had the
package as their home package is to unintern them, it should not
remove access to them, and thus should not have the effect of removing
the type. it will preclude a reader with standard syntax from finding
the symbol, but it should not change the results of operations on
existing classes, structures, instances, etc.

...
From: Damien Kick
Subject: Re: Removing types
Date: 
Message-ID: <vfc2wxhr.fsf@email.mot.com>
"Paul F. Dietz" <·····@dls.net> writes:

> Damien Kick wrote:
> 
> > I'm interpretting the above to mean that if one UNINTERNs the
> > symbol that names a type created by either DEFSTRUCT, DEFCLASS, or
> > DEFTYPE, or uses DELETE-PACKAGE as something of a heavy handed
> > UNINTERN, that this will also effectively remove the type that it
> > named.  However, I can't seem to find anything in the CLHS that
> > supports my interpretation.  Am I understanding Kent correctly?
> 
> If you remove all access to the symbol naming the type, you have,
> in effect, removed the type, since its presence or absence can no
> longer have any observable effect on a conforming program.

True.  However, if the type is not actually removed, it'll still
increase the memory size of the Lisp.  After asking the question, I
played around with CMUCL a bit.

    * (defclass squib
        ()
        ())
    #<STANDARD-CLASS SQUIB {808E811D}>
    * (setq *class* *)
    #<STANDARD-CLASS SQUIB {808E811D}>
    * (maphash (lambda (k v)
               (when (eq k 'squib)
                 (print v)))
             pcl::*find-class*)
    (#<STANDARD-CLASS SQUIB {808E811D}>
     #<STANDARD-GENERIC-FUNCTION (PCL:CLASS-PREDICATE SQUIB) (2) {808CBC81}>) 
    NIL
    * 
    (maphash (lambda (k v)
               (when (eql (car v) *class*)
                 (print "Found, it!")))
             pcl::*find-class*)
    ; Note: Variable K defined but never used.

    "Found, it!" ; 
    NIL

And so there seems to be an entry in the hash.  I'm sure there are all
kinds of other things done in the implementation and that this
PCL::*FIND-CLASS* is not the One Place To Go for whether or not one
can find a type but it is something that I can "see".

    * (setf (find-class 'squib) nil)
    NIL
    * 
    (maphash (lambda (k v)
               (when (eql (car v) *class*)
                 (print "Found, it!")))
             pcl::*find-class*)
    ; Note: Variable K defined but never used.
    ; 
    NIL

Using the SETF form removes the entry from the hash.  But this is not
the case with UNINTERN.

    * 
    (setq *class*
          (defclass squib () ()))
    #<STANDARD-CLASS SQUIB {8091EFED}>
    * 
    (maphash (lambda (k v)
               (when (eql (car v) *class*)
                 (print "Found, it!")))
             pcl::*find-class*)
    ; Note: Variable K defined but never used.

    "Found, it!" ; 
    NIL
    * (unintern 'squib)
    T
    * (maphash (lambda (k v)
               (when (eql (car v) *class*)
                 (print "Found, it!")))
             pcl::*find-class*)
    ; Note: Variable K defined but never used.

    "Found, it!" ; 
    NIL
    * 

But UNINTERN seems to keep the entry in the hash.  If one continued to
DEFCLASS and then UNINTERN, the Lisp would run out of memory, if from
nothing other than the hash using all the available memory.  Using
SETF on the FIND-CLASS of a type defined with DEFSTRUCT does, FWIW,
seem to remove the entry in PCL::*FIND-CLASS*, at least on CMUCL.  But
the hyper-spec tells me:

    The class associated with a particular symbol can be changed by
    using setf with find-class; or, if the new class given to setf is
    nil, the class association is removed (but the class object itself
    is not affected). The results are undefined if the user attempts
    to change or remove the class associated with a symbol that is
    defined as a type specifier in this standard.

So I'm assuming that *FIND-CLASS* is the PCL/CMUCL implementation for
FIND-CLASS; the association has been removed but that doesn't mean
that the class object still doesn't exist in memory and so DEFCLASS
followed by (SETF (FIND-CLASS SYMOBL) ...) might soak up all available
memory, too.

<pause>

So, Paul's statement is probably accurate, AFAIK.  However, drilling
down another level, is there a defacto standard for removing types
from Lisp implementations?  IIRC, the standard doesn't call for GC,
either, but most(all?) Lisps use GC.  Is there something similar with
regards to removing types from a running Lisp?