1 Frequently Asked Questions
- What is the difference between the wx and wxcore libraries?
- The wxcore library provides the core interface to the wxWidgets API (in WxcClasses). Furthermore, it provides some useful abstractions for the Haskell programmer. However, the library just uses functional abstraction: no overloading, new monads, or other fanciness. The wx library is build on top of the wxcore library and uses more advanced abstraction mechanisms, like overloading, to provide useful features like properties and attributes.
- Does wxHaskell support multiple threads?
- Not currently. GHC 6.0 does not support process threads by default, and Haskell concurrency does not work correctly (yet) with a GUI event loop. However, as the wxWidgets manual says, multiple threads are not always a good solution. For example, doing a long computation in a separate thread in order to show a progress bar, is normally better solved by calling wxcApp(Safe)Yield periodically, or by doing the computation in an idle event handler. wxHaskell does have support for event driven, asynchronous input streams; see the Process sample for more details. Note that one should use the wxHaskell provided mutable variables (Var) to be assured for thread safeness in the future.
- Why haven't you created a purely functional interface (Fudgets, Fran, ..)</dt>
- Since the design of high-level GUI libraries (like Fruit or Fudgets) is still much of a research issue, we opted for creating a "medium level" interface: an interface that does create useful functional abstractions but does not provide a new programming model (i.e. everything is in the IO monad and uses simple mutable variables to communicate state across different event handlers). Hopefully, this makes it easy for others to create new functional programming models on top of the basic interface. However, in our experience, the current model is already quite adequate and certainly much friendlier than the equivalent C++ code – having computations as first-class values makes Haskell the ultimate imperative language :-)</dd>
- Why wxWidgets?</dt>
- Well, there are many good reasons for using wxWidgets:
- wxWidgets is free software but you can still write commercial applications with it.
- It is a thin wrapper around native UI elements giving native look-and-feel.
- It is a comprehensive library that is portable across many GUI platforms.
- There even exists a wxUniversal port that just uses a screen buffer (and giving up on native look-and-feel!) that can be used on embedded devices.
- The development community is very active (ranked among the top 25 of most active projects on sourceforge).
- The library is mature (in development since 1992).
- The library not only provides GUI abstractions but also an API for databases, sockets, editors, etc.
- We could generate a Haskell marshalling layer automatically from the wxEiffel binding.
- There exist many more language bindings, with wxPython as the most widely known (and used?).
But of course, there are also some downsides:
- wxWidgets is free software :-). In itself not bad but it also means that we are dependent on the time and effort of volunteers. For example, the MacOS X port lags somewhat behind and the documentation of the Qt toolkit is in general better (although the wxWidgets documentation is pretty good too).
- It is a huge library. Not a problem in itself but it can be somewhat intimidating.
- The wxEiffel binding is only partially type checked and manually written; it is better when the marshalling code can be generated from the real wxWidgets type signatures (but alas, this involves writing either a C++ parser or writing bindings with SWIG). We might someday start to use the wx.NET wrapper as it seems better structured for use with an automatic marshalling program.
- Why don't you use Qt (or FLTK, or ..) ?</dt>
- Of course there exist some other good GUI libraries and maybe they would be good choices too (here is a nice overview). However, many libraries have important drawbacks. For example, the programming model of Swing is inconvenient to use from Haskell.