Tuesday, May 31, 2005

For the first time ever in my long and illustrious programming life, I have said to myself "Wow, I sure could use multi-methods right about now". ("They grow up so fast, don't they?") Of course, I can't be sure that multi-methods will really solve my problems, but a cursory glance at the situation seems to indicate that such a direction will be fruitful. A rough overview - I need have a scheduler that will take an event and return a random "next" event, which must be a sensible choice (by which I mean that one can't have an ArriveEvent before a LeaveEvent, unless one goes into the realm of philosophy; I would normally, but not today, gentle reader!). It seems that this means a set of methods operating on each derived class:

void schedule (ArriveEvent &e) { ... }
void schedule (ShopEvent &e) { ... }

But, of course, the events themselves are stored as Event *s; to make sure the right schedule is called, one needs double-dispatch!

Event *e = new ArriveEvent ();
scheduler.schedule (e); // Oops! Not polymorphic on argument type!

Consequently, for the first time I have come across a situation where a pattern has suggested itself - in this case, Visitor. Ahh, things are really falling into place now!

I suppose this harkens back to the post I made a while ago about the need for some of the design patterns in a language that does support multi-methods, like Lisp. The pattern solution is more elegant than any function pointer hacks or the like, but the amount of code required to express a "simple" concept (dangerous phrase, eh?) is a bit inordinate in this case I think. I think one sign of the limitation of this neat trick is that I find myself thinking about the problem in a multi-method way, but the implementation seems to present some sort of gap with this idea in my head - ideally, they should both be able to seamlessly fit together. But that is the ultimate aim of all programming languages, is it not!?

Update: Wouldn't you know it, it turns out that double-dispatch is indeed a valid solution to this problem, but, its services are not required. That is, my whole abstraction which created the need for double-dispatch is unfounded. This came after much thought and a lot of energy spent on trying to tweak a design which I was quite proud of; I felt it was complicated only as a direct result of the limitations of C++. I had a brainstorming session where I exchanged ideas with another unfortunate soul, and at the end of it I felt physically drained. I confronted all the uncertain areas of my proposed design and laid them open to critique and possibly demolition, yet at the end of the gruelling session, most of them stayed intact. Tired but somewhat content, I revelled in what I thought was a clever approach to a seemingly simple problem. However, the bane of every developer is perhaps the fact that sometimes the seemingly simple is the simple!

Before I attempted to validate my theories with the lecturer, I had a vague feeling of unrest, and was uncertain of why this was. It seemed to me that my ideas were so uncharacteristic of the level of thinking that we had applied thus far, and this sowed some doubt in my mind whether I was going towards a laughably obfuscated solution. The lecturer did not use such a harsh term, but seemed to think the whole idea quite excessive and unnecessary. I tried to justify my approach by citing the achievement of a powerful abstraction, but the more I tried, the more I started to realize that perhaps I was completely wrong after all. It's mildly humourous how the whole thing has panned out - imagine lying in a field, content and at peace, but then all of a sudden finding yourself sinking into the ground! Perhaps that is not an altogether ill-formed analogy, because that is rather like what was going on in my head. It is not an unusual experience for me, actually. It seems that the few times that I do have an original idea, it is hopelessly misdirected and off track; if there is any pattern at all, it is that I apply abstractions too early, and in too much abundance at the wrong times. It is ironic that I have another design I am working with at the moment where the exact opposite seems to be true; the system is almost bewildering in its simplistic design, yet I cannot see suitable abstractions suggesting themselves in any meaningful way. The situation is a total reverse - I look on with wry amusement at some alternate approaches, and spot areas which I think display the same characteristics that I just mentioned. Yet I would be willing to wager that it is these alternate solutions which will prove to be more flexible and generic; outrageous!

I was advised that perhaps I think "too hard" about some problems, yet I don't know that that's true. I seem to be very selective about the cases where I do give serious thought to problems - much like my alter-ego then, 'twould seem that my instincts are always wrong! I apply a pattern of thinking in the wrong context. But, how much of a flaw is this? I think that perhaps it is not as serious as all that, if only because the mistakes not only help cement the nature of the lesson nature, but also open possibilities to other modes of thinking. For instance, the epiphany of using a Visitor pattern will probably remain with me for a while; the result of a mistake, but nonetheless a very powerful discovery I think.

But at the same time I find part of me getting tired with the mental exertion required. I spend mornings reading about analytical scalpels and neatly dividing items with clear strokes, but it would seem that my evenings end up in frustration at my own blunt cuts. It is hard sometimes to put this into perspective, as with most things. For sometimes...ahhh, the yearning to somehow apply these pristine notions and concepts is overwhelming! As it stands, I have to restrain myself in an attempt to reign in any potential mental blocks - such things, I now believe, are possible as a result of too much focus on the abstract and aesthetic, or at the very least, as the result of inexperienced focus (guilty as charged!).

"How funny it all is!", I feel compelled to conclude. I suppose all I can really do is laugh and try another day (naturally abstracting away the burden of it being an assessment!).

No comments: