From: Jonathan Bachrach
Subject: Re: about run-time class (type) checks...
Date: 
Message-ID: <g5zp8ydo8h.fsf@oroboros.harlequin.com>
  David Bakhash <·····@bu.edu> writes:

  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.

as other people have said, sealing allows methods to be chosen
statically in Dylan.  

  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

Glenn Burke and I submitted a paper to ECOOP-99 on just this subject:

  Partial Dispatch: Optimizing Dynamically-Dispatched Multimethod
  Calls with Compile-Time Inferred Types and Run-Time Feedback

  We present a novel approach to reducing the overhead of dynamically
  dispatched multimethod calls by specializing call-site caches with
  information from compile-time inferred types, run-time profile
  information, and dynamic state.  Dylan supports the development of
  reusable components using separate compilation.  Unfortunately,
  separate compilation can starve the compiler of information necessary
  to perform full static dispatch of multimethod calls, for example when
  dispatch is performed on abstract types.  Dylans sealing construct
  provides a way to gain back partial class hierarchy information and in
  this paper, we present an approach to gaining back complete class
  hierarchy information by delaying the construction of dispatch caches
  until the whole class hierarchy is available at run-time.  Run-time
  call-site caches can then be constructed as specialized decision trees
  built from disjointness and concrete-subtype operations on actual
  arguments combined with compile-time inferred types injected into the
  run-time. Unnecessary decision steps can be avoided and often run-time
  dispatch can be completely eliminated.  Furthermore, profile
  information gained through call-site instrumentation can be fed back
  to reduce space and time overhead.  Finally, run-time dispatch state
  can be utilized to avoid multimethod dispatch steps in recursive
  calls.  We present a mechanism for tracking this information in the
  face of incremental development and dynamic class creation.  Together,
  these techniques can bring the average overhead of multimethod 
  dispatch on par with single argument dispatch.

This can work in CLOS using just declared types (and would probably be
a win), but it is much more powerful in Dylan because (1) sealing
permits even higher quality type inference (especially in the face of
separate compilation) permitting precise type estimates for arguments
at call-sites and (2) abstract classes allow for further
specialization of types inferred to be abstract classes by knowing
that there can't exist direct instances of them.

jonathan bachrach
harlequin inc