Say you have an application that you will need to release for two or more platforms. For the sake of an argument, let’s say that these platforms are Windows and Mac OS X. (I’ll come back later to why one of those two is not Linux.) Now, keeping in mind the virtues of programming as well as an aspiration to code optimally, pick a tool to make the best application.
I am guessing that quite a lot of you picked a platform-independent language, like Java, or a cross-platform toolkit, like Qt. I personally would like to argue that you are wrong.
There are two extremes of top-to-bottom platform independence solutions. The first kind is the Java approach: make it a goal to be as self-hosting as possible. Use your own drawing for the UI. Taken to the extreme, it is a goal that no matter where your application is run, it will run and work the same. The other kind is the wxWidgets approach: adapt as far as possible to the current underlying platform. If you’re making a button, definitely call through to the native APIs for making a button.
(Neither Java nor wxWidgets are purely of one mind - Java run on Mac OS X gets Apple’s Java runtime, where the Swing classes actually call through to draw native controls. But this isn’t the point. They are useful to describe the general thrust of the two extremes.)
These two extremes are both a bad way to go in creating a compelling application. The Java approach suffers from the platform-unto-itself problem - your Java application only really fits in next to other Java applications. Azureus and Eclipse are perfect examples of this syndrome. In the end, Java apps are cross-platform in the way that any platform can run Java apps, not in the way that any Java app will feel native.
The wxWidgets approach, instead, sounds good from the outset. What really gets you is that every platform’s implementation of all the widgets collectively is subtly different, and that individual widgets can be really different. (A toolbar in Mac OS X is unlike any toolbar in Windows, except perhaps a single, fully expanded Office Ribbon tab.)
So why does this happen? This happens because the third rule of good coding — the first and second rules are that you do not talk about Fight Clgood coding — the third rule of good coding is: reuse code, damn it. And so, with this in mind, the optimal thing is to write everything cross-platform, and reuse the whole thing. I mean, right?
Right?
I have personally had it up to here with cross-platform apps. What do I, and every other sane computer user on the planet, want? We want applications that act native and look native. Cross-platform toolkits have improved, but they are far from able to deliver this now, if ever. I propose instead another solution.
Write the part of your app that does not directly deal with the user interface in a cross-platform kind of way; then use a native UI solution. This is not new. This has worked before. Yes, it means you will have to implement the user interface twice. Guess what? Unless you’re using two platforms that work exactly alike, you will have to duplicate some code in order to make it work. Why not go the extra mile and make it work just like it should on every platform, all over the application?
C is traditionally the “universal solvent” - the ultra-portable language where all reusable code is written. Other languages are also widely capable of working well on multiple platforms and recently C#, with Mono, has been dragged kicking-and-screaming into this club. The interesting thing is that I would recommend even here that .NET Windows Forms (or XAML) are used for Windows and other solutions like Gtk# for Linux and Dumbarton and Cocoa for Mac.
I promised you to mention Linux more. Linux has no native UI for GUI applications. The really brave or really stupid or those who really really have to can use X directly (not pretty, in more ways than one). Most sane people use one of two popular toolkits — Qt (recommended for KDE) and GTK+ (recommended for GNOME). Of those, only one has its origins in a real application. GTK+ stands for “the GIMP Toolkit”; Qt is a cross-platform toolkit. (Another toolkit that’s mostly historical is Motif, designed to look like Windows 3.11.)
If Linux has trouble making it on the desktop (and I’d sure like for it to succeed), I think this may be part of the explanation.