On how GUI toolkits need more than a good language to be great

A few days ago I was pointed to this very interesting post from an Apple engineer who had jumped off the Java bandwagon after getting a peek of Cocoa.

One could think that Java being more advanced that Objective C (though perhaps not in all areas), such a move would be foolish, but I’m pretty sure there were more than a few nods among his readers on this one.

Building a good GUI toolkit is a craft of its own, and requires much more than just a good language. I like Java (even though I find it somewhat boring), but it’s a shame that Swing would be such clumsy a tool to build apps with. The toolkit I know the most is Qt, and even though it’s based on probably the most intricate language in common use today (C++), I still think that it kicks Swing’s butt in term productivity.

I suppose anyone who has used Swing long enough has his own list of its biggest annoyances. Mine is limited to layouts and the pervasive use of listeners (or more precisely the need to implement an interface or derive a class just to handle a frickin’ UI event). I guess this is because Qt is particularly more convenient than Swing in these specific areas. Layouts are hard to do, that’s understood. The ones offered with Swing have the fundamental problem that none of them is really that good out of the box, and always requires extensive tweaking. The obvious use is never the right one. Listeners, however, stem from another design mistake : preferring a “clean” API over a convenient one, or more generally, enforcing a principle to the point that it becomes a dogma and is no longer connected to reality. I can’t think of a better way to turn a something that’s meant to help into just the opposite.

Swing declares that everything should fit some OO design. Qt recognizes that listeners are a feature in itself, and implements it at the language level instead (at the price of a meta compiler). Note that Qt also has event handling based on overriding virtual methods, like in Swing. However this is limited to events generated by the graphic system (widget hide/expose, mouse button or key press), because these need to be processed quickly. But user interactions on widgets (a checkbox has been toggled, an item in a list has been selected, etc…) go through Qt’s signal/slot mechanism, which is much more practical. It has two big advantages : requiring much less code and making loose-coupling between the event emitted and the object processing it much easier. It somehow lets C++ make a tiny step into the realm of weak-typed languages like Python or Ruby. When you write

connect(myButton, SIGNAL(clicked()), thehandler, SLOT(wasClicked()))

no check is made at compile time that ‘thehandler’ actually has a ‘wasClicked()’ method. This might sound strange, but it’s actually quite convenient on several ways. For one, it opens a whole realm of runtime fiddlings. It also means that at this stage, ‘thehandler’ needs only to be defined as a QObject. No need to #include its whole class declaration, thus less dependencies.

So there you have it : a toolkit committing a cardinal sin against the language it’s based on, adding something which OO designers would probably frown upon, all for the sake of convenience. And it works.

On the contrary, by enforcing an API to follow a design paradigm consistently all throughout, disregarding the practical problems it inevitably raises, you turn it into something which will be more easily read (or written) by the machine than by the programmer.

Leave a Reply

Your email address will not be published. Required fields are marked *