From: Barry Margolin
Subject: Re: Collecting EQL specialized methods.
Date: 
Message-ID: <PbTH2.287$p4.115193@burlma1-snr2>
In article <··············@copernico.parades.rm.cnr.it>,
Marco Antoniotti  <·······@copernico.parades.rm.cnr.it> wrote:
>
>Hi,
>
>I am working on a small application that potentially has a lot of code
>like
>
>(let ((zut (make-instance 'zot)))
>   (defmethod meth ((z (eql zut))) #| do stuff |#)
>
>I know I can set up a macro WITH-INSTANCE-METHODS that did exactly
>what I want and added a bunch of unwind-protected REMOVE-METHODS at
>the end.
>
>However, wouldn't it be nice if the newly created methods were somehow
>colleted when the where no longer needed?

The problem is determining when they're no longer needed.  To do this, it
seems like CLOS would have to use weak references for EQL specializers and
for references to methods in generic function object.  That way, the
specializer won't prevent the object it specifies from being collected, and
the generic function's method table won't prevent the method from being
collected.

It's doable, but seems like lots of work for a situation that's extremely
uncommon.  EQL specializers are usually used for long-lived things, such as
keywords or special cases of a generic function (e.g. if you had a
multiplication generic function, you might create methods specialized on
(EQL 0) and (EQL 1)).  Leaving the unusable methods around shouldn't cause
any operational problems, and shouldn't have a performance impact if method
dispatch is implemented well (usually using a hash table).

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

From: Marco Antoniotti
Subject: Re: Collecting EQL specialized methods.
Date: 
Message-ID: <lwsob32nd7.fsf@copernico.parades.rm.cnr.it>
Barry Margolin <······@bbnplanet.com> writes:

> In article <··············@copernico.parades.rm.cnr.it>,
> Marco Antoniotti  <·······@copernico.parades.rm.cnr.it> wrote:
> >
> >Hi,
> >
> >I am working on a small application that potentially has a lot of code
> >like
> >
> >(let ((zut (make-instance 'zot)))
> >   (defmethod meth ((z (eql zut))) #| do stuff |#)
> >
> >I know I can set up a macro WITH-INSTANCE-METHODS that did exactly
> >what I want and added a bunch of unwind-protected REMOVE-METHODS at
> >the end.
> >
> >However, wouldn't it be nice if the newly created methods were somehow
> >colleted when the where no longer needed?
> 
> The problem is determining when they're no longer needed.  To do this, it
> seems like CLOS would have to use weak references for EQL specializers and
> for references to methods in generic function object.  That way, the
> specializer won't prevent the object it specifies from being collected, and
> the generic function's method table won't prevent the method from being
> collected.

Or, I suppose you could write special code for the collector.

> It's doable, but seems like lots of work for a situation that's extremely
> uncommon.

I realize that it may be a lot of work. Maybe it will be an idea for
some tweaking of the CMUCL garbage collector(s).

> EQL specializers are usually used for long-lived things, such as
> keywords or special cases of a generic function (e.g. if you had a
> multiplication generic function, you might create methods specialized on
> (EQL 0) and (EQL 1)).  Leaving the unusable methods around shouldn't cause
> any operational problems, and shouldn't have a performance impact if method
> dispatch is implemented well (usually using a hash table).

I agree with this - but only partially.

Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa
From: Kelly Murray
Subject: Re: Collecting EQL specialized methods.
Date: 
Message-ID: <36F13543.5443D920@IntelliMarket.Com>
Good example for showing why EQL specializers can be eliminated.

To specialize a method for a specific instance doesn't make any
sense to me, but it does make sense to specify a subclass 
for that instance, and specialize the method for the subclass.
And given one wants to use every obscure feature of CLOS,
you can then just use change-class to convert an instance
to the uniquely special class for the distinguished instance.
Or get serious, and call ensure-class to cons-up 
a new subclass at runtime. 

(class the-special-zot (zot))

(method meth ((z the-special-zot)) ...)

(let z = (make 'zot)
  do
  (change-class z 'the-special-zot)
  )
  
Or another simpler way is to have a class slot for your
distinguished instance, and conditionalize the method on it.

(class zot (..) 
 (the-special-zot :initform nil :allocation :class)
 )
(method meth ((z zot))
 (if (eql (slot-value z 'the-special-zot) z)
  then (my-most-special-zot-meth z)
  else ..))

-Kelly Murray  
  
  



Marco Antoniotti wrote:
> 
> Barry Margolin <······@bbnplanet.com> writes:
> 
> > In article <··············@copernico.parades.rm.cnr.it>,
> > Marco Antoniotti  <·······@copernico.parades.rm.cnr.it> wrote:
> > >
> > >Hi,
> > >
> > >I am working on a small application that potentially has a lot of code
> > >like
> > >
> > >(let ((zut (make-instance 'zot)))
> > >   (defmethod meth ((z (eql zut))) #| do stuff |#)
> > >
> > >I know I can set up a macro WITH-INSTANCE-METHODS that did exactly
> > >what I want and added a bunch of unwind-protected REMOVE-METHODS at
> > >the end.
> > >
> > >However, wouldn't it be nice if the newly created methods were somehow
> > >colleted when the where no longer needed?
> >
> > The problem is determining when they're no longer needed.  To do this, it
> > seems like CLOS would have to use weak references for EQL specializers and
> > for references to methods in generic function object.  That way, the
> > specializer won't prevent the object it specifies from being collected, and
> > the generic function's method table won't prevent the method from being
> > collected.
> 
> Or, I suppose you could write special code for the collector.
> 
> > It's doable, but seems like lots of work for a situation that's extremely
> > uncommon.
> 
> I realize that it may be a lot of work. Maybe it will be an idea for
> some tweaking of the CMUCL garbage collector(s).
> 
> > EQL specializers are usually used for long-lived things, such as
> > keywords or special cases of a generic function (e.g. if you had a
> > multiplication generic function, you might create methods specialized on
> > (EQL 0) and (EQL 1)).  Leaving the unusable methods around shouldn't cause
> > any operational problems, and shouldn't have a performance impact if method
> > dispatch is implemented well (usually using a hash table).
> 
> I agree with this - but only partially.
> 
> Cheers
> 
> --
> Marco Antoniotti ===========================================
> PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
> tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
> http://www.parades.rm.cnr.it/~marcoxa
From: Barry Margolin
Subject: Re: Collecting EQL specialized methods.
Date: 
Message-ID: <L7bI2.321$p4.116294@burlma1-snr2>
In article <·················@IntelliMarket.Com>,
Kelly Murray  <···@IntelliMarket.Com> wrote:
>Good example for showing why EQL specializers can be eliminated.
>
>To specialize a method for a specific instance doesn't make any
>sense to me, but it does make sense to specify a subclass 
>for that instance, and specialize the method for the subclass.
>And given one wants to use every obscure feature of CLOS,
>you can then just use change-class to convert an instance
>to the uniquely special class for the distinguished instance.
>Or get serious, and call ensure-class to cons-up 
>a new subclass at runtime. 

But you still have to provide extra code in an UNWIND-PROTECT to delete
this singleton subclass and remove the method from the generic function.
The whole issue is wanting Lisp to realize that the extra method can be
garbage collected automatically.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Marco Antoniotti
Subject: Re: Collecting EQL specialized methods.
Date: 
Message-ID: <lwpv653kro.fsf@copernico.parades.rm.cnr.it>
Kelly Murray <···@IntelliMarket.Com> writes:

> Good example for showing why EQL specializers can be eliminated.

No they cannot. They are a good idea brought into CL from various
"frame based" languages. The idea of 'instance' methods is good and I
believe useful (with limitations). Unfortunately, the "decoupling"
of methods over generic functions makes it tricky for the GC to work.

> 
> To specialize a method for a specific instance doesn't make any
> sense to me, but it does make sense to specify a subclass 
> for that instance, and specialize the method for the subclass.
> And given one wants to use every obscure feature of CLOS,
> you can then just use change-class to convert an instance
> to the uniquely special class for the distinguished instance.
> Or get serious, and call ensure-class to cons-up 
> a new subclass at runtime. 
> 
> (class the-special-zot (zot))
> 
> (method meth ((z the-special-zot)) ...)
> 
> (let z = (make 'zot)
>   do
>   (change-class z 'the-special-zot)
>   )
>   
> Or another simpler way is to have a class slot for your
> distinguished instance, and conditionalize the method on it.
> 
> (class zot (..) 
>  (the-special-zot :initform nil :allocation :class)
>  )
> (method meth ((z zot))
>  (if (eql (slot-value z 'the-special-zot) z)
>   then (my-most-special-zot-meth z)
>   else ..))
> 

You are hand waving here. The method METH in your first example is not
collected. And in the second case you are special coding a lot of
stuff you really do not want to.  On top of that you are not solving
the problem of:

	(dotimes (i *qqq*)
	   (let ((x (make-instance 'x)))
	      (defmethod qwe ((y (eql x))) i)
              (qwe x)))

I know it is an extreme case which you should work around, but it is a
problem which - I am conviced - should be dealt with by special code
in the GC.

Cheers
From: Pekka P. Pirinen
Subject: Re: Collecting EQL specialized methods.
Date: 
Message-ID: <ixhfr8vxsj.fsf@gaspode.cam.harlequin.co.uk>
Barry Margolin <······@bbnplanet.com> writes:
> The problem is determining when they're no longer needed.  To do this, it
> seems like CLOS would have to use weak references for EQL specializers and
> for references to methods in generic function object.  That way, the
> specializer won't prevent the object it specifies from being collected, and
> the generic function's method table won't prevent the method from being
> collected.

But it _should_ prevent the method from being collected, expect if the
specializer has died, so you need something more complicated.  Also,
the method could die, if the gf has died, even if the specializer is
alive.  LispWorks does pruning like this (for multi-methods and all
kinds of specializers), but only when tree-shaking; it's too
expensive.
-- 
Pekka P. Pirinen    Harlequin Group plc, Cambridge, UK
A feature is a bug with seniority.  - David Aldred <david_aldred.demon.co.uk>
From: Marco Antoniotti
Subject: Re: Collecting EQL specialized methods.
Date: 
Message-ID: <lwpv5sohw7.fsf@copernico.parades.rm.cnr.it>
·····@harlequin.co.uk (Pekka P. Pirinen) writes:

> Barry Margolin <······@bbnplanet.com> writes:
> > The problem is determining when they're no longer needed.  To do this, it
> > seems like CLOS would have to use weak references for EQL specializers and
> > for references to methods in generic function object.  That way, the
> > specializer won't prevent the object it specifies from being collected, and
> > the generic function's method table won't prevent the method from being
> > collected.
> 
> But it _should_ prevent the method from being collected, expect if the
> specializer has died, so you need something more complicated.  Also,
> the method could die, if the gf has died, even if the specializer is
> alive.  LispWorks does pruning like this (for multi-methods and all
> kinds of specializers), but only when tree-shaking; it's too
> expensive.

It seems to me that there are two differentissues here.

1 - is a GENERIC FUNCTION alive or not?
2 - is a method with EQL specializers invokable or not?

In case 1 I beleieve that you can remove the 'unbound' GF safely
(e.g. after a FMAKUNBOUND).

In the second case, apart form problems of 'constantness' (cfr. the
huge recent thread) it seems to me that this would just be an extra
pass in the garbage collector either using all the method objects as
roots or by setting up special gc tables rooted on objects
participating in EQL specializers. How much more expensive this would
be I do not know. But let's not kid ourselves. This is a problem of
reclaiming memory by tying together code and 'object' by 'object
identity'.  Somehow it should be taken care of.  As per the criteria
for collectability of a multi-method with EQL specializers, unless I
am missing something, you do away with the thing when one of the EQL
parameters has gone away.

Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa