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