Pinderkent

Pain and glory from the trenches of the IT world.

Getting to know today's practical GUI toolkits.

Posted on Tuesday, March 24, 2009 at 1:23 AM.

For years now, Andy Tai has done a great job of maintaining the The GUI Toolkit, Framework Page. It's a very extensive list of GUI toolkits and frameworks, both open source and commercial, for a wide variety of languages and platforms. In fact, it's almost too complete. Many of the toolkits listed are no longer developed or became obsolete years ago. So my aim here is to narrow down his huge list to the toolkits and frameworks that are practical, from a developer's perspective, and worth using today.

First and foremost, we have Qt. Many consider it to be the premiere C++ GUI toolkit. That's not surprising, of course. It has a long history of being developed as a commercial product, first by Trolltech and then by Nokia after they acquired Trolltech. Nevertheless, it has also been released under a variety of open source licenses throughout its lifetime. Given its maturity and use in a wide variety of software systems, including KDE, Opera and Google Earth, it has become known as a very reliable, portable, high-performance and high-quality toolkit.

Although Qt is written in C++, a variety of bindings have been developed for other languages. Some of the most notable include QtAda for Ada 2005, PyQt for Python, PHP-Qt for PHP, QtRuby for Ruby and qtHaskell for Haskell. In short, it proves to be a great toolkit, almost regardless of what language or platform you're using.

After Qt, we can consider wxWidgets to be the next most practical GUI toolkit. Like Qt, it is written in C++, is available under an open source license, is extremely portable, and can allow for the development of a professional-grade UI. Also like Qt, there are bindings for a number of popular languages, including wxPython for Python, wxRuby for Ruby, wxHaskell for Haskell, wxPerl for Perl, and even wxErlang for Erlang and wxLua for Lua.

One of the main benefits of wxWidgets over other GUI toolkits is its use of native controls. This allows applications developed using it to integrate nearly seamlessly with the host operating system, even while remaining somewhat portable. So while other toolkits offer themes that try as best as possible to emulate the behavior and appearance of the native platform's UI toolkit, this is often done imperfectly. A perceptive user will know they're not using a native application. But with wxWidgets, we typically don't find this happening.

After wxWidgets, GTK+ can be considered the next most usable toolkit. One difference that it has from Qt and wxWidgets is that it is written in pure C, rather than C++. While this makes language bindings easier to develop, it does have some drawbacks. One such drawback is that it makes extensive use of the GObject object system to provide object-oriented-like functionality for C. This typically feels inferior to using an actual OO language.

While it is portable to other platforms, its origin as an X Window System toolkit can still be felt. Applications using the Windows port of GTK+, for instance, typically don't truly feel like a native Windows app. Nevertheless, the Windows ports of applications like GIMP and Inkscape are usable and reliable. For the best experience, however, it's usually recommended to use GTK+ applications within an environment such as GNOME or Xfce, both of which are built upon it.

Like wxWidgets and Qt, GTK+ also has a wide variety of language bindings. Some of the most widely used include gtkmm for C++, PyGTK for Python, Gtk2-Perl for Perl, Ruby-GNOME2, PHP-GTK for PHP, Gtk2Hs for Haskell, Gtk# for the languages supported by Mono and .NET, and LablGTK for OCaml. Unlike Qt and wxWidgets, which are quite usable for large applications written in their native language (C++), it's probably best to use GTK+ from one of its more mature bindings, such as gtkmm, PyGTK or Gtk#, rather than from straight C.

Swing is relatively old and well-known. Originally Java-centric, it is becoming a more viable option as languages like Scala and Clojure, which target the JVM, become more prevalent. Other language implementations targeting the JVM, like Jython for Python and JRuby for Ruby, make it even more usable. Unfortunately, it does have a number of problems. It has never been known for offering high performance, and is somewhat memory-intensive. Applications written using Swing never truly feel like native applications, even when using a platform-specific theme. The API itself is also quite messy, having accumulated much cruft after a decade. And many developers don't want the extra baggage associated with the Java runtime, which makes it less appealing for those not writing an application specifically for the Java platform.

The FOX Toolkit is likely the most practical toolkit after Qt, wxWidgets, GTK+ and Swing. Like Qt and wxWidgets, it's written in C++. But unlike them, it doesn't offer as much of an accompanying framework. So in many respects it's a much more lightweight toolkit. And unlike some other toolkits, it doesn't (yet) include support for themes, so it has its own unique look and feel that is reminiscent of the traditional Windows look and feel. Nevertheless, it is portable and released under an open source license.

Unlike the aforementioned toolkits, the FOX Toolkit doesn't have as wide of a variety of language bindings. FXRuby for Ruby is a mature and usable binding, but others, like the FXPy binding for Python and the EiffelFox binding for Eiffel, have stagnated. So the FOX Toolkit is probably best used from its native C++ or from Ruby.

FLTK is similar to the FOX Toolkit in many ways. It's also written in C++, is portable, and is more lightweight than toolkits like Qt and wxWidgets. Unfortunately, it doesn't have as many bindings for other languages, and the ones that do exist (like the Ruby wrapper and pyFLTK for Python) aren't updated very frequently. So while FLTK is usable, it probably isn't the best option for more complex applications that are expected to have a long lifespan.

There are many other GUI toolkits out there, both commercial and open source. In terms of cost, portability, usability, user-experience and programming language interoperability, the toolkits mentioned above are typically the best options. Qt is perhaps the most flexible option for writing high-quality, portable GUI applications, followed closely by wxWidgets. GTK+ is good for software running on UNIX-like systems, but doesn't offer as seamless as an experience on other platforms. Swing is typically the choice for those targeting the JVM. And toolkits like FOX Toolkit and FLTK provide alternatives for those who don't want the baggage of the larger and more complete frameworks. While no toolkit is perfect for every piece of software, picking Qt, wxWidgets, GTK+, Swing, FOX Toolkit or FLTK should prove to be a safe, viable, practical and capable choice.

Permalink: http://pinderkent.phumblog.com/post/2009/03/getting_to_know_todays_practical_gui_toolkits
Share:

The Java platform needs an overhaul, not just the Java language.

Posted on Sunday, March 22, 2009 at 4:28 PM.

There has been some discussion lately on several blogs about Java and its feasibility as a programming language for practical development these days. The articles I'm talking about are Bruce Eckel's "The Positive Legacy of C++ and Java", "Java as Legacy Language" by Kas Thomas, and "Is it time to retire Java?" by David Arno.

The general theme of all three articles is that the Java language has not kept up with the times. That's not to suggest that it's useless or will disappear any time soon, however. Anyone with experience in industry knows that there is an absolutely huge amount of Java code out there, critical to many business operations. But it is true that Java does not offer the productivity it once did. Relative to languages like C and C++, it did allow for more complex systems to be developed with less effort, and in a shorter period of time. But languages like Python and Ruby have been attacking it from beneath, and now prove to be a better option for many software development projects.

The general feeling after reading those articles is that although the Java programming language isn't as beneficial as it once was, it did provide us with the JVM, and this in turn proves to be a useful platform for languages and implementations like Scala, Clojure, JRuby and Jython.

I'm not so sure that this is the case. The JVM has never really been a spectacular platform. Performance problems have plagued it from the very beginning. Some of the problems are inherent to the Java language itself, namely in limiting what optimizations the compiler, runtime and programmers can perform. Although there have been improvements relating to JIT compilation, for instance, I think a lot of the performance problems of Java have only been mitigated somewhat by hardware consistently getting much faster during the late 1990s and most of this decade.

When the topic of Java performance comes up, some people like to toss around various microbenchmarks showing that some obscure task can be done relatively quickly using code running on a Java virtual machine. Unfortunately, these results don't translate well to the real world, where applications tend to be far more complex. Part of the reason why desktop Java apps never really took off, for instance, was because most of them felt sluggish relative to other applications written in languages like C and C++. Application startup time has also always been a problem with applications running on the JVM. Were it not for server-side applications typically being long-running and typically running on more powerful hardware, it's doubtful that Java would have made the inroads it managed to make there.

Bloat is another issue plaguing the Java platform. The earliest versions of the runtime had installers that were 2 to 5 MB in size. While that seems like almost nothing today, in the mid-1990s that was a hassle to download over a dail-up connection, especially if one was paying by the hour. Although not as much of a problem now due to the prevalence of broadband Internet connections, the Java 1.6.0_12 runtime installer for x64 Linux is still relatively large at over 18 MB.

Even today, with many computers having two or more gigabytes of RAM, we see Java applications using a disproportionate amount of memory. On Linux using Sun's 64-bit 1.6.0_12 runtime, we see the Scala 2.7.3.final REPL using 593 MB of virtual memory, with 153 MB resident, as reported by top. And this is just after starting up the REPL while it's still at its first prompt, without having entered any expressions that may have increased the memory usage. Some applications are even worse. Just after startup, before loading any projects, NetBeans 6.5.1 is already using 1029 MB of virtual memory, with 249 MB resident. We can't blame just the JVM for such problems, but we also can't overlook its involvement.

The Java class library was once one of the key selling points of Java and the Java platform. It provided a lot of common functionality in a manner that could be easily reused by developers, thus increasing their productivity dramatically. But over the past decade, we've seen a variety of libraries for other languages arise that provide the same functionality, but often with much nicer and effective abstractions or APIs. Microsoft's .NET class library is one of the most widely used. Faced with such competition, the Java platform just doesn't look as attractive as it once did.

The Java class library is also starting to really show its age. While many classes and methods have been officially deprecated, they do remain around cluttering up the library. Others, like the AWT, are impractical for use today, but still must remain around due to later technologies, like Swing in the case of AWT, being built directly upon them.

Furthermore, a great deal of the classes don't make good, if any, use of generics, enumerations and the various other language features introduced since Java 5. The benefits of having such language features in Java are negated when many of the core library classes we use don't support them. We're often stuck still using integer constants where enumerations would be much more appropriate, for instance. Unfortunately, there is great reluctance to change the library in ways that would impact compatibility with older Java applications. So it's unlikely we'll ever see these problems fixed up appropriately.

When it comes to running non-Java languages on the JVM, we end up with even more problems. A language like Scala offers features, functionality and concepts that we just don't find within the scope of the Java language. So although it can be used, actually using the Java standard class library from a language like Scala negates many of the benefits of using the newer language in the first place. While such interoperability and reuse is often touted as a benefit of using advanced languages that target the JVM, I fear it's actually a significant downside, as it doesn't promote the effective use of the new language features that really do boost programmer productivity or application quality. They're crippling themselves by trying to reuse existing code that doesn't fit their philosophy.

So while languages and implementations like Scala, Clojure, Jython and JRuby are bringing more impressive languages to the JVM, they can't really do anything about the poor performance or the excessive resource usage of the JVM, nor can they do much about the poor state of the Java class library. But I'm also not suggesting that we have a viable alternative. Even though they recently released Parrot 1.0.0, it's still not a platform suitable for widespread production deployments. The Mono project is making some good progress, although they're typically playing catch-up to Microsoft's implementation, and don't have complete freedom to dictate how their runtime should behave. LLVM is perhaps the most promising alternative, but as the name implies, it is very low-level, not offering functionality we've come to expect from virtual machines (like garbage collection).

If the Java platform is to continue to serve us into the future, I suspect a significant overhaul is necessary. Performance and memory usage improvements to the JVM would be of a huge benefit to many. Better support for acting as the target of non-Java languages would likely be beneficial, as well. And a complete cleanup and reworking of the Java class library is a must. Unfortunately, this would not be a small undertaking, and would require huge amounts of time and effort. So it seems unlikely at this time that we'll see such a rework occur. This is somewhat unfortunate, as now is probably the best time to do it, while languages like Scala and Clojure have really started to mature, but just before they become so widely used that momentum against change develops.

Permalink: http://pinderkent.phumblog.com/post/2009/03/the_java_platform_needs_an_overhaul_not_just_the_java_language
Share:

RIAs have always been about marketing, and not about providing valuable technical solutions.

Posted on Saturday, March 14, 2009 at 5:41 PM.

There has been a lot of hype over the past several years about RIAs, Rich Internet applications. And hype is essentially all that we've gotten. The main problem with RIAs is that they don't let us do anything truly new. In short, they don't help us solve real problems. This derives from the fact that their use and the use of the development tools used to create them has been driven mainly by marketing and evangelism, rather than by need.

Today's common RIA technologies include Microsoft's Silverlight, Adobe's Flex and Sun's JavaFX. From a technical perspective, none of them are truly remarkable or innovative. Silverlight is essentially Microsoft's .NET stack within the browser. Flex and JavaFX are somewhat worse, in that they use sub-par languages like ActionScript in Flex's case, and JavaFX Script in the case of JavaFX.

So we end up with platforms that are heavily sandboxed (that is, intentionally limited in capability) due to being browser-based, and developer productivity that is crippled by the use of languages like JavaFX Script and ActionScript. Even Java applets, available since 1995, offer a more flexible and developer-friendly platform.

Those platforms and frameworks don't really allow us to do anything that we couldn't already do with typical desktop applications or even JavaScript-based Web apps. One common use is playing streamed media, which is something that various desktop applications have offered for many years now. Otherwise, we often see them used for low-quality 2D games, which have also been available for decades. And they prove to be quite terrible for business applications, often combining the worst of Web application development with the worst of desktop application development.

Their inherent lack of technical merit is likely why we've seen them pushed more by marketing forces and stealth bundling, rather than seeing their uptake driven by them naturally providing a more productive, efficient way of solving problems using software. The whole emphasis on 100 million downloads is a good indicator of this.

Over the past several months, I've done some part-time consulting with a company that developers custom apps for a variety of clients. Unfortunately, some of their clients have requested RIAs, with most of the emphasis being placed on Flash/Flex and JavaFX. Over lunch time discussions with some of the developers, I've gotten the impression that feelings are quite mixed. The developers coming from a more traditional background of developing desktop client-side software using languages like C++, Java and C#, including myself, have a more negative opinion of these platforms. We see the regression. On the other hand, those coming from a Web development background are more likely to embrace them, because they often aren't aware that there's much beyond JavaScript and HTML.

My hope is that the development community as a whole gets over this RIA fad sooner, rather than later. We've got more pressing matters to concern ourselves with. Namely, we need to start making better use of functional languages, rather than half-baked scripting languages like ActionScript and JavaFX Script. We need to return our focus to developing practical apps that actually help make others more productive, rather than providing yet another way to play video.

Permalink: http://pinderkent.phumblog.com/post/2009/03/rias_have_always_been_about_marketing_and_not_about_providing_valuable_technical_solutions
Share:

The role of nesting in limiting the size and complexity of functions and methods.

Posted on Wednesday, March 11, 2009 at 1:53 AM.

I read an article today that discussed the optimal size of methods or functions. The article references a number of books and academic studies regarding this topic. As with most things, it appears that what's needed is a healthy balance. In this case, it's a matter of distributing complexity in a way that makes the entire application more understandable and easier to work with, while at the same time not making individual methods of functions too complex.

I've worked with a number of codebases over the years that have taken very different approaches to problems such as these. Some have set a very strict limit on the size of functions or methods, in terms of lines of code. Others have exhibited much more flexibility.

All in all, I think that strict lines-of-code limits typically aren't beneficial. When using an OO language, this often translates into classes with a large number of small private methods. While each method may be less than, say, 25 lines of code, the class as a whole isn't necessarily easier to understand or worth with. Following the flow of execution soon becomes an act of skipping between these small methods. In many cases we find that 10 methods of 20 lines each can be more difficult to follow than one method of 200 lines.

It doesn't help that many mainstream languages don't allow for nested functions. When using a language like Java, for instance, we often run into cases where we have a large method that we want to separate out into smaller methods, but our only choice is really to create one or more private methods in the same class. If the class consists of several such methods that we'd like to break up, then things can become more awkward as we have a proliferation of private methods that are really only used by one other method. Ideally, we could define functions or methods that are defined within the "parent" method. This doesn't reduce the overall size of that method, but it does allow for it to be broken up into smaller pieces of logic.

Noted C++ export Herb Sutter gives some examples of how to simulate nested functions using C++. I found another article showing a technique using C# delegates. Arguably, these techniques make the code more difficult to follow. GCC's extension allowing for nested C functions is somewhat cleaner, but at the cost of portability.

One benefit of using a functional programming language is that most allow for, if they don't outright encourage, the use of nested functions. The Standard ML of New Jersey homepage specifically mentions this as a benefit of Standard ML in its summary of the language, for instance. Some examples can be seen within the 'Merge Sort' section of the Wikipedia article on Standard ML. Functions exist within the context where they are most needed and most useful, but otherwise remain out of the way.

A good rule of thumb might be to make methods or functions just as long as they need to be to complete one task, and to do that task well. Immutability, which is core to functional programming, also helps encourage this sort of coding. We end up writing short, local functions that return values rather quickly, rather than writing longer functions or methods that manipulate state stored in global variables or class member variables. So in the end, it may come down to using a language or at least a language implementation that allows for nested functions or methods. If that's not a possibility, there are workarounds to simulate such functionality while using languages like Java and C++. And if that's not a possibility, then it may just be best to have slightly longer methods.

Permalink: http://pinderkent.phumblog.com/post/2009/03/the_role_of_nesting_in_limiting_the_size_and_complexity_of_functions_and_methods
Share:

"Adaptive PHP" techniques help ensure bugs, unmaintainability, and other problems.

Posted on Friday, March 06, 2009 at 2:34 AM.

The recent 6 Signs of Adaptive PHP article gives some examples of different PHP coding techniques. Unfortunately, it only bothers to cover the supposed "benefits" of each, without any consideration of how such techniques can prove to be problematic.

The first technique suggests passing all arguments to a function within a single associative array. The supposed "benefits" all promote laziness, namely in that all parameters become potentially optional, and less or no change is needed to any invocations of the function if parameter changes are made.

Not mentioned in that article were the drawbacks. One obvious problem is the vastly increased verbosity, both when it comes to handling default values, and when it comes to invoking the function. Default parameter values, as offered by languages like C++ and even VB.NET, are syntactically superior to this approach.

Even the very concept itself is flawed, as it's much better in terms of maintainability and clarity to have an explicit list of parameters. For one thing, this technique makes it much less obvious to other programmers how to call the function. Given the general lack of documentation associated with most PHP applications, it's likely that anybody wishing to use the function would have to consult the code of the function itself. It also inhibits the ability of the interpreter to check that the correct number of arguments have been passed to the function.

Furthermore, if one has a function that has so many optional parameters that such a technique is needed, perhaps too much is being done in that single function. It would appear that such a function is a good candidate for heavy refactoring.

The second suggestion recommends checking for functions and classes before making use of them, such as those exposed by a plugin module. This sounds risky. When it comes to plugins, the host application should insist that any plugins conform to a strict API. Working with plugins that may just decide not to export a certain required function, for instance, is a recipe for disaster. If a plugin module doesn't provide the proper interface, it should not be loaded.

The third suggestion is perhaps the only one that's sensible. It suggests using require_once() to prevent multiple inclusions of some external PHP code. Indeed, this typically is a good idea.

The fourth suggestion recommends that associative arrays be used to return multiple values from a function. While this isn't as bad of an idea as the use of an associative array to store parameter values, this seems to indicate that PHP should offer a more lightweight construct such as the tuples found in languages like Python and Standard ML. Sticking with what PHP already offers, perhaps even an object could be returned, rather than an associative array.

The fifth suggestion recommends the use of an __autoload function. The very existence of this function suggests that PHP has some serious shortcomings when it comes to allowing for the sensible separation of code. On one hand, this sort of dynamic loading is the sort of functionality that PHP should offer transparently.

Furthermore, it indicates a laziness on the part of PHP developers who wish to write code making use of classes defined in other source files, but who are unwilling to put forth the small amount of effort needed to explicitly include such files.

In addition, the three notes in the __autoload documentation should make developers hesitant to use such functionality. It appears that it interferes with the semantics of exception handling, it's not available when using PHP in its interactive mode, and has risks associated with the validity of the class names passed to it. Frankly, it sounds like yet another PHP "bandage" meant to patch over problems in the language and programmer laziness, while at the same time introducing far more severe problems.

The final suggestion recommends that the directory of the script be determined by calling dirname(_FILE), especially for the purposes of location other PHP files to include. For the given example, the use of a relative path should be sufficient.

The PHP community has a long history of not fixing the problems with their language and its most common implementation. Far too often we've seen "solutions" like these, which end up being messier and more convoluted than had the problem with PHP itself just been fixed sensibly. It's no wonder that so many PHP Web apps are buggy, full of security holes and essentially unmaintainable; the language itself is inherently broken, the workarounds are just as broken and full of caveats, and together they result in nothing but problems.

Permalink: http://pinderkent.phumblog.com/post/2009/03/adaptive_php_techniques_help_ensure_bugs_unmaintainability_and_other_problems
Share:
Feeds
  • RSS 2.0 Feed
  • Atom 2.0 Feed
Tags
Archives