[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: OBJECT-ORIENTED CLX
Okay, so lets drop the discussion of where to perform OO thingies and talk
about how to build something on top of CLX to make it easier to use.
Granted that an object-oriented interface to *anything* makes it easier to
use, but it must also be noted that when you OO'ify anything your performance
degrades to a certain extent.
In the case of CLX we have a nice platform to access a non-OO system (i.e. X),
and we could potentially expand CLX to contain OO'ism and make it more useful
(or should I say usable). In any event, the question of changing a primary
interface like CLX, which many people may wish to utilize w/o OO additions,
does not seem to make much sense (e.g. should we change the UNIX system call
interface to only be C++?).
The question then becomes ``what should we build on *top* of CLX to make it
better for our particular application domain?'' Let's say that we want to
build an object-oriented CLX (CLX++) which provides all the functionality of
CLX, but is located in the xlib++ package (don't flame about the dumb names).
If we utilize this type of strategy we can preserve the primary interface and
make use of its functionality and at the same time override the neccessary
low-level functionality for any modifications we see fit.
So now lets look at what we want to change. Well, Kerry wants to have
a SATISFIES subclassing mechanism for event processing. Moon tells us that
there is some CLOS magic to get this functionality, and Warren doesn't think
that it will be fast enough. There is also the question of why even provide
something like this feature when what you obviously want is two-levels of
method discrimination. In addition, I said that you could allow an experienced
programmer to utilize hooks to speed up event processing to avoid the cons'ing
of event objects and gratuitous method discrimination -- I hope you understood
that I didn't expect the CLX++ programmer to understand *all* of CLX, but only
how to make use of the hooks in CLX++ to access certain functions and
structures defined at the CLX level.
Whew! A lot of differing viewpoints and amazingly enough I think these
different ideas support the notion that no one implementation will serve the
needs of all users.
As I pointed out in my original message, X is not going to start sending
out new events which are subtypes of events defined in the protocol spec,
so why should the user be allowed to subclass event objects? Also, why
cons (or use resources) for event objects that are immediately going to be
destructured in the discrimination process? This is *very* expensive.
Sure it's expensive, but for the novice it makes using the system very
easy and for both the expert and the novice it makes debugging a *lot*
easier (trust me, I made extensive use of this feature when using my *own*
system - I guess that would make me an expert :-). No one ever said that you
always had to cons up event objects.
I think this approach requires the users to be experts to get any real work
done. The problem with streamlining one layer and building an "extensible"
and easy to use layer on top of it is that it creates a very large gap
between what's easily doable and what's tollerable. Pushing
object-oriented programming to a layer on top of CLX has exactly this
pitfall. I'd rather see CLX be designed with performance AND extensablity
in mind up front.
I also would love to see CLX have super performace and be totally extensible,
sounds great... uh, I don't think you can do this trick, 'cause the users will
always come back and say ``make it faster'' and any OO'ism you add are going to
require a performance hit. In the design I implemented for XCL and XCLOS, the
users were not experts, but the hooks provided made it extremely easy for
any programmer to determine bottlenecks in her code and avoid making use of
the OO stuff in the XCLOS layer. For example, lets look at a simple example:
(let ((event (make-instance 'enter-window)))
(setf (state event) :ignored)
(defmethod enter-window-event-handler ((self text-menu-item) (event integer))
(declare (ignore event))
(let ((e (xcl:x-next-event)))
(if (and (= (xcl:x-event-window e) (id self))
(= (xcl:x-event-type e) xcl:*leave-window*))
(return-from enter-window-event-handler nil))
(xcl:x-invert-window (id self))
(t (xcl:x-invert-window (id self)))))
(defmethod default-handler ((self text-menu-item) (event enter-window))
(declare (ignore event))
(let ((e (get-next-event)))
(if (and (eq (window e) self)
(eq (class-of e) (class-named 'leave-window)))
(return-from default-handler nil))
(t (invert self))))
In this example, the default-handler() is the method which is utilized if there
is no mapping for an event-window event on a text-menu-item window. However,
when the mapping for the event exists, the system will make use of the
optimized method. It is a method in this example since I might want to make
use of the text-menu-item enter-window-event-handler in some subclass of
I guess what I really want to get across is that most novices can become
experts if the system gives them a gradual learning curve and does not say that
they must either know everything, or not be able to utilize underlying
features. I took it from your comment that you didn't think that such a path
could be implemented, but the hooks I built into XCLOS provided various paths
to encourage the user to optimize various aspects of her code, w/o having to
know a lot about XCL.
I would hope that whatever is built on top of CLX retains the original CLX
interface and allows the users of the new system to make use of supported
hooks to optimize their code.