From: David Bakhash
Subject: about run-time class (type) checks...
Date: 
Message-ID: <cxj90gr4ofu.fsf@engc.bu.edu>
hey,

One of the cool things about CLOS is that generic functions can check
the type of an object, and then dispatch the proper method for those
arguments.

My questions pertain to the way in which this happens:

First and foremost, I'd like to know if implementations of CLOS have
the ability to look at declarations at compile-time and thus know
which method should be used, in order to prevent this from being done
at run-time.

Secondly, provided that the above is true, and CLOS does just that,
I'd like to know whether CLOS can do something similar if only _some_
of the types are known.  For example, consider a generic function
which dispatches a method based on the classes of its first two
arguments, each of which can be one of two classes.  Thus, let's
assume that this generic function has four methods, depending on the
types (classes) of its first 2 arguments.  Now, consider the situation 
where we declare one of those two types.  Ideally, the compiler would
be smart enough to only do run-time type-checks on the yet unknown
field.  I'd like to know if this is how it's actually done, or if it's 
done so that if anything is unknown, then the same typecase block is
used.

thanks,
dave

From: Barry Margolin
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <XmZ82.28$5M.5382@burlma1-snr1.gtei.net>
In article <···············@engc.bu.edu>, David Bakhash  <·····@bu.edu> wrote:
>First and foremost, I'd like to know if implementations of CLOS have
>the ability to look at declarations at compile-time and thus know
>which method should be used, in order to prevent this from being done
>at run-time.

This generally isn't feasible.  Declaring that a variable is of a specific
class means that it could be any subclass of that class.  This could even
include subclass that don't exist at compile time.  Note that this only
applies to standard-class and structure-class types; builtin-class types
have a known class hierarchy, and can't be subclassed by the programmer.

Dylan has the notion of "sealing" a class, which specifies that no
subclasses will be defined.  This allows such an optimization to be done
with user-defined classes.

>Secondly, provided that the above is true, and CLOS does just that,
>I'd like to know whether CLOS can do something similar if only _some_
>of the types are known.  For example, consider a generic function
>which dispatches a method based on the classes of its first two
>arguments, each of which can be one of two classes.  Thus, let's
>assume that this generic function has four methods, depending on the
>types (classes) of its first 2 arguments.  Now, consider the situation 
>where we declare one of those two types.  Ideally, the compiler would
>be smart enough to only do run-time type-checks on the yet unknown
>field.  I'd like to know if this is how it's actually done, or if it's 
>done so that if anything is unknown, then the same typecase block is
>used.

That's conceivable, although depending on the implementation of the
dispatch table, it may only be feasible if certain parameters are
declared.  Multiple dispatch specifies a priority to different parameters
(to resolve ambiguities), so it might only be able to skip the type
dispatch if the type of the higher priority argument (the first, by
default) is known.

In practice, I don't think any CLOS implementations perform this
optimization.  The main optimization in many CLOS implementations is
caching the combined method for class combinations that have been used.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.
From: David Bakhash
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <cxj67bvryyp.fsf@engc.bu.edu>
Barry Margolin <······@bbnplanet.com> writes:

> In practice, I don't think any CLOS implementations perform this
> optimization.  The main optimization in many CLOS implementations is
> caching the combined method for class combinations that have been used.

That's too bad that CLOS can't optimize such things.  This is really
evil, because I would think that declarations + generic function calls 
can expand into invoking the right method, despite what you said about 
subclasses, and that feature that Dylan has that CLOS doesn't.

Are there reasons that CLOS decided not to add that feature
(i.e. sealing a class)?  What are the drawbacks?  I recall seeing
something like this in Java, suggesting that it's there to allow for
significant optimizations.

dave
From: Sunil Mishra
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <efyzp97hzae.fsf@spanker.cc.gatech.edu>
I don't think it makes much of a difference that this optimization is not
performed. If you think about it, if you run the method only once, the cost
to the whole program is negligible. If the method (with the same argument
combinations) is invoked many times, caching should give you very similar
performance, so you pay the penalty only once. The implementation wins by
being able to avoid a lot of the complexity in this type of optimization.

Sunil

David Bakhash <·····@bu.edu> writes:

> Barry Margolin <······@bbnplanet.com> writes:
> 
> > In practice, I don't think any CLOS implementations perform this
> > optimization.  The main optimization in many CLOS implementations is
> > caching the combined method for class combinations that have been used.
> 
> That's too bad that CLOS can't optimize such things.  This is really
> evil, because I would think that declarations + generic function calls 
> can expand into invoking the right method, despite what you said about 
> subclasses, and that feature that Dylan has that CLOS doesn't.
> 
> Are there reasons that CLOS decided not to add that feature
> (i.e. sealing a class)?  What are the drawbacks?  I recall seeing
> something like this in Java, suggesting that it's there to allow for
> significant optimizations.
> 
> dave
From: Brian M. Dennis
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <jad862fqv6.fsf@mochajava.ils.nwu.edu>
Sunil Mishra <·······@spanker.cc.gatech.edu> writes:

> I don't think it makes much of a difference that this optimization is not
> performed. If you think about it, if you run the method only once, the cost
> to the whole program is negligible. If the method (with the same argument
> combinations) is invoked many times, caching should give you very similar
> performance, so you pay the penalty only once. The implementation wins by
> being able to avoid a lot of the complexity in this type of optimization.
> 
> Sunil

The Self project did in fact demonstrate that such optimizations could
be useful. You not only reduce method resolution time but you can do
further analysis in the method body with stronger assumptions about
object types, potentially leading to elimination of various type
checks, among other things.

However, it is not obvious that their techniques are directly
applicable to Common Lisp although it should be pointed out that Self
is arguably even more dynamic.

-- 
inscrutable
						--bri
From: Tim Bradshaw
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <ey3lnkqzxd0.fsf@todday.aiai.ed.ac.uk>
* David Bakhash wrote:
> Are there reasons that CLOS decided not to add that feature
> (i.e. sealing a class)?  What are the drawbacks?  I recall seeing
> something like this in Java, suggesting that it's there to allow for
> significant optimizations.

I'd be interested in knowing this too, if anyone who was there knows.
I suspect it's because the notions of what you might want to be able
to do and what might make sense to do just weren't sorted out enough
at the time, and perhaps there was (is?) a notion that it should be
possible to add via the MOP anyway.  Now dylan has (?) sorted things
out it might be easier to retrofit.

Obviously a vendor can simply add sealing to CLOS by some
declarations, so it's not excluded in any case.

--tim
From: Marco Antoniotti
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <lwr9uin1c9.fsf@copernico.parades.rm.cnr.it>
Tim Bradshaw <···@aiai.ed.ac.uk> writes:

> I'd be interested in knowing this too, if anyone who was there knows.
> I suspect it's because the notions of what you might want to be able
> to do and what might make sense to do just weren't sorted out enough
> at the time, and perhaps there was (is?) a notion that it should be
> possible to add via the MOP anyway.  Now dylan has (?) sorted things
> out it might be easier to retrofit.
> 
> Obviously a vendor can simply add sealing to CLOS by some
> declarations, so it's not excluded in any case.
> 

IMHO, this would be the worst of possible worlds for the community as
a whole.


-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 10 03 17, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Tim Bradshaw
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <ey3g1axzeo5.fsf@todday.aiai.ed.ac.uk>
* Marco Antoniotti wrote:

> IMHO, this would be the worst of possible worlds for the community as
> a whole.

Why?  A vendor can decide on some declarations or other syntax for
sealing, document them, and provide a sample implementation (their
own).  Other vendors can use that syntax too, if they wish.

What mechanism is better than this?  I seriously doubt that some group
getting together and deciding on some way of specifying this in the
inevitable absence of an implementation is a better way to do it.

--tim
From: Pierre Mai
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <87lnkohkaa.fsf@dent.home.cs.tu-berlin.de>
Tim Bradshaw <···@aiai.ed.ac.uk> writes:

> * Marco Antoniotti wrote:
> 
> > IMHO, this would be the worst of possible worlds for the community as
> > a whole.
> 
> Why?  A vendor can decide on some declarations or other syntax for
> sealing, document them, and provide a sample implementation (their
> own).  Other vendors can use that syntax too, if they wish.

Especially since the proposed declaration would only be an
optimization "hack", so that implementations that don't support the
declaration can just ignore them (or you can conditionalize them out), 
and will suffer no evil consequences (apart from running a little
slower, possibly)...

You just can't require all implementations to support the same things, 
especially optimizations.

Regs, Pierre.

-- 
Pierre Mai <····@acm.org>               http://home.pages.de/~trillian/
  "One smaller motivation which, in part, stems from altruism is Microsoft-
   bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]
From: Marco Antoniotti
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <lw67bo1b06.fsf@copernico.parades.rm.cnr.it>
Tim Bradshaw <···@aiai.ed.ac.uk> writes:

> * Marco Antoniotti wrote:
> 
> > IMHO, this would be the worst of possible worlds for the community as
> > a whole.
> 
> Why?  A vendor can decide on some declarations or other syntax for
> sealing, document them, and provide a sample implementation (their
> own).  Other vendors can use that syntax too, if they wish.

What if they *would not* wish so? Then you'd have two different
implementations of basically the same thing. (..and have the nuisance
of either writing less portable code or to sprinkle it with a lot of
#+ and #-).

> 
> What mechanism is better than this?  I seriously doubt that some group
> getting together and deciding on some way of specifying this in the
> inevitable absence of an implementation is a better way to do it.
> 

That is a very good point. A "reference implementation" (as pointed
out by a private email to me) would be a very good thing indeed and
probably the only way to go to convince the vendors to implement these
features. However, I am throwing the stone and hiding the hand here,
since I do not have the time to do such a thing.

Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 10 03 17, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Tim Bradshaw
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <ey3btlcry3a.fsf@todday.aiai.ed.ac.uk>
* Marco Antoniotti wrote:
> What if they *would not* wish so? Then you'd have two different
> implementations of basically the same thing. (..and have the nuisance
> of either writing less portable code or to sprinkle it with a lot of
> #+ and #-).

Don't buy from that vendor!  Scream and shout at them!  Tell them
right now that if they do something like that you will take your trade
elsewhere! You are paying them real money for this stuff, they damn
well ought to do what you say.

The vendors would, of course, like to tie you into their proprietary
stuff, and if there was a monopoly (like in microsoftland) then users
will really get tied in, and will end up living in hell.  But I don't
think the vendors are nearly powerful enough in the Lisp market to do
this.  I do think that people need to *tell* them this, often.

--tim
From: Barry Margolin
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <Uee92.59$5M.12307@burlma1-snr1.gtei.net>
In article <···············@engc.bu.edu>, David Bakhash  <·····@bu.edu> wrote:
>Are there reasons that CLOS decided not to add that feature
>(i.e. sealing a class)?

We didn't "decide not to add" it.  I wasn't on the subcommittee that
designed CLOS, but AFAIK the idea never actually came up (certainly never
at the plenary level).  CLOS was patterned mostly after New Flavors and
LOOPS, and I don't think either of them had such a notion.  What we have is
more in keeping with Lisp philosophy, which allows extreme dynamism.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.
From: Andrew Shalit
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <lo8btlj38u8.fsf@shell2.shore.net>
Barry Margolin <······@bbnplanet.com> writes:

> In article <···············@engc.bu.edu>, David Bakhash  <·····@bu.edu> wrote:
> >Are there reasons that CLOS decided not to add that feature
> >(i.e. sealing a class)?
> 
> We didn't "decide not to add" it.  I wasn't on the subcommittee that
> designed CLOS, but AFAIK the idea never actually came up (certainly never
> at the plenary level).  CLOS was patterned mostly after New Flavors and
> LOOPS, and I don't think either of them had such a notion.  What we have is
> more in keeping with Lisp philosophy, which allows extreme dynamism.

Right.  When we introduced the notion of sealing in Dylan, X3J13 was
already well on its way to finishing up its work.  It would have been
way too late, I think, to try to plug it back into that process.

At least one vendor---Digitool---has provided some sealing functionality.
MCL supports a PRIMARY CLASS declaration.  This restricts how a class
can be used with multiple inheritance.  Basically, you can only
inherit from multiple primary classes if those classes inherit from
each other.  The result of this restriction is that slots declared in
primary classes can be placed at the same offset in all instances, allowing
very fast slot access.  I'm not sure if MCL supports a SEALED CLASS
declaration.

Finally, I should note that Dylan's SEALED CLASS declaration is different
from Java's FINAL declaration in an important way.  A final class in
Java cannot have any subclasses.  A sealed class in Dylan can have
subclasses, but all of its direct subclasses must be in the same
compilation unit (library) as the class itself.  Thus in Dylan you
can seal entire branches of the class hierarchy, not simply leaf classes.
This additional functionality is important in the creation of fixed
and efficient abstract interfaces.  A similar distinction exists
between Java's final methods and Dylan's sealed methods.

  -Andrew
From: Erik Naggum
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <3121821477157482@naggum.no>
* David Bakhash <·····@bu.edu>
| This is really evil, because I would think that declarations + generic
| function calls can expand into invoking the right method, despite what
| you said about subclasses, and that feature that Dylan has that CLOS
| doesn't.
| 
| Are there reasons that CLOS decided not to add that feature (i.e. sealing
| a class)?  What are the drawbacks?  I recall seeing something like this
| in Java, suggesting that it's there to allow for significant
| optimizations.

  sealing is great for a language and environment where most of the hard
  stuff is done in the compiler and the program just _runs_.  sealing is
  nigh evil for a language and environment where most of the hard stuff is
  done at load- or run-time and programs _evolve_ during their lifetime.

  the problem is that just as we have no way to make a variable "unspecial"
  because of the impact on the already-compiled code, there is probably no
  sealing because it would be necessary to have an "unseal" mechanism, too,
  and that would impact already-compiled code just like special bindings.

  the same goes, incidentally, for other (global) proclamations.  if you
  declare a function's signature, should it still be possible to redefine
  it with, say, an additional optional argument, or with new argument
  types?  which types should it be optimized for?  should we have an
  UPGRADED-ARGUMENT-TYPE function?

  I use Common Lisp for a reason.  high performance is nice, but when its
  absence becomes a significant hurdle for an application, I have already
  figured out _where_ it matters the most by writing everything in Common
  Lisp and profiling the application.  like, today, I reimplemented a
  _tiny_ part of my application as a 30-line C program, and also changed
  the algorithm to reduce the traffic across the interface (a pipe -- it
  has to be running in a separate process).  it wasn't the kind of thing
  Common Lisp is good at, but the fact that this trivial C program takes a
  huge load off of the Lisp scheduler and leaves it to Linux to deal with,
  also means that the rest of the application can now become more complex
  before we need to upgrade from the 133 MHz Pentium it is currently
  running on.  (the _only_ reason we use that kind of machine is that we
  have lots and lots of them.  because such hardware is dirt cheap, it is
  also expected to die, so we use two of them in parallel, instead.  we're
  in the curious position that the hardware may crash and burn, but the
  software must be kept running without noticeable interruption.  this is
  not the kind of stuff you do in six months in C, but that's what it has
  taken me to do it in Common Lisp, and only now am I beginning to worry
  about performance.  a 133 MHz Pentium isn't worth shit these days, but
  thanks to Linux and Allegro CL, a very significant investment in hardware
  can now have a _much_ longer life-span.  the savings on the hardware side
  almost pays for my work.  who'd've thought _that_ about Common Lisp?)

  oh, one other thing -- by discovering this tiny CPU-intensive part, we
  were able to obtain a ten-fold overall system performance increase.
  since we had about the same factor when going from the old system to the
  new, the _observable_ response times have dropped to less than 100 ms,
  compared to 3 to 10 seconds in the old system.  now, it wouldn't take a
  genius to spot the CPU-intensive part, but it did take Lisp to isolate it
  so cleanly and enable the ten-fold increase in performance.  C coders
  just don't _do_ what what my hybrid solution does, anyway.  so, for me,
  high performance computing on dirt cheap hardware comes with Lisp, and
  low performance computing on more expensive hardware was what C gave us.
  and isn't it perfectly ironic that because I _don't_ worry about high
  performance, _that's_ what I get, while the dude who wrote the previous
  version in C was mortally afraid of wasting cycles, and so wrote a system
  so slow it had to be replaced?  the strangest thing is that most of what
  you really want from life obey the same apparent contradiction.

  I'm not sure how much sealing classes would have helped in my scenario.

#:Erik
-- 
  The Microsoft Dating Program -- where do you want to crash tonight?
From: Marco Antoniotti
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <lw1zmi9ak0.fsf@copernico.parades.rm.cnr.it>
Barry Margolin <······@bbnplanet.com> writes:

> In article <···············@engc.bu.edu>, David Bakhash  <·····@bu.edu> wrote:
> >First and foremost, I'd like to know if implementations of CLOS have
> >the ability to look at declarations at compile-time and thus know
> >which method should be used, in order to prevent this from being done
> >at run-time.
> 
> This generally isn't feasible.  Declaring that a variable is of a specific
> class means that it could be any subclass of that class.  This could even
> include subclass that don't exist at compile time.  Note that this only
> applies to standard-class and structure-class types; builtin-class types
> have a known class hierarchy, and can't be subclassed by the programmer.
> 
> Dylan has the notion of "sealing" a class, which specifies that no
> subclasses will be defined.  This allows such an optimization to be done
> with user-defined classes.

This is equivalent to Java 'final' attributes.

I suppose that something like

(defclass z (x y)
   (<slots>)
   (:attributes :sealed #| or :final |# :unchangeable <other-attributes>))

:sealed (or :final) have the meaning that the class cannot be
subclassed and :unchangeable has the meaning that instances of this
class cannot change class.

This could be worked in the language. (Maybe this could be
accommodated by meta-classes; I don't know).  However the biggest
problem would be to convince Franz, Harlequin and Digitool to use the
same semantics and non to make it too difficult for it to be
re-implemented in the PD lisps.

Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 10 03 17, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Steven M. Haflich
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <36673709.A9A36585@franz.com>
Marco Antoniotti wrote:

> This could be worked in the language. (Maybe this could be
> accommodated by meta-classes; I don't know).  However the biggest
> problem would be to convince Franz, Harlequin and Digitool to use the
> same semantics and non to make it too difficult for it to be
> re-implemented in the PD lisps.

I would say instead that the biggest problem is that something like this
shouldn't be standardized until someone has done a prototype
implementation to debug the semantic details,  to learn something
about the performance gains, and to investigate what it might be like to
do traditional late-everything Lisp development in such an environment.
This is more-or-less how CLOS was adopted by X3J13.

Don't misunderstand -- I have long thought sealing would be a wonderful
language addition and I would be eager to work on it myself.

Once some prototype is proven the language design, I don't think there
would be significant problem getting vendors to implement it (especially
if it could be defined to have null semantric content in conforming programs,
like type declarations. and therefore ignorable in implementations that don't
want to deal with it :-).