Introducing WxGeneric
May 3, 2008
I recently decided to rethink and reimplement AutoForms. This post will be the first of a series that explains the hows and whys of this reimplementation.
Why AutoForms need a replacement
AutoForms started simply as a library to generically construct GUI forms, such as a settings dialog. But as development has progressed more and more features has been been added. It has gotten to the point where AutoForms tries to be a complete GUI library on top of WxHaskell, in stead of just a library to generically construct widgets in cooperation with WxHaskell.
The feature creep has let to several problems:
- Less separation of concerns than possible
- Too much to maintain and develop
- For potential users of a AutoForms I am asking a lot, as they will have to understand a hole new and complex library.
- By exploring many different features, non have really been explored to a satisfactory level. AutoForms has become Jack of all trades, master of none.
I have dealt with these issues in two ways. Firstly I have created an interface to AutoForms (called AFWx) which is very simple for a person that already knows WxHaskell. Secondly to better separate concerns, I have been factoring out the different parts into independent modules.
While these remedies have helped, it was not enough. I wanted a library that focused on generically constructing Widgets from data types. As such, large parts of the code in AutoForms were unneeded. And large parts needed to be changed. Therefore starting from scratch seemed attractive. While I was not sure it was the best choice it did seem like an experiment worth performing. And in retrospect I think it turned out really well.
Another issue that led me to reimplementation were composability. Just like most data types are composed of other data types, a library like AutoForms needs to compose widgets to bigger widgets. Unfortunately WxHaskell lacks in composability. Thus AutoForms contains the WxM monad to compose widgets. The interface of the WxM monad is considerably different from ordinary WxHaskell code and those places a burden on the user. But as I recently discovered it is possible to achieve composability, while still keeping the WxHaskell look and feel. This makes a strong argument for scraping the WxM monad. And as the WxM Monad is a central piece of AutoForms, it also makes a strong argument for reimplementing AutoForms.
The Reimplementation
The reimplementation resulted in not one, but two new libraries. The first library is called WxGeneric and constructs widgets generically. In contrast to AutoForms, it do not try to reinvent the GUI library. While it does make GUI creation easier, most of the GUI application code will still look like ordinary WxHaskell code. Indeed most of the GUI application code will call WxHaskell directly.
When constructing AutoForms, I discovered that some of the hardest to implement code was not specific to any one GUI toolkit. It therefore seemed natural to abstract this code into a separate library. This library is called SybWidget and WxGeneric builds upon it. However, as it is very difficult to make a generalization from just one example, I also refactored AutoForms to use SybWidget. The refactoring indeed resulted in changes to SybWidget that made it more generally useful. It is my hope that GUI toolkits similar to WxHaskell (like Gtk2Hs) will find SybWidget useful and implement there own generic widget libraries.
Separating the WxHaskell specific parts from the rest, allowed me to make a library that do not use the IO monad. This makes it possible to test SybWidget with QuickCheck. For some functions the important aspect to test was not so much varying values, but varying types. Here QuickCheck approach do not make much sense and I opted for HUnit instead. I use Haskell Program Coverage for measuring SybWidget’s test coverage.
Future of AutoForms
The simplicity of WxGeneric (as compared to AutoForms) is very attractive, but it is not without cost either. For example AutoForms tries to be “intelligent” about the automatic layout of widgets. This “intelligence” will be lost when using WxGeneric. Also AutoForms has better static type safety than both WxGeneric and WxHaskell. In the future I might try to develop these ideas further. Either as part of AutoForms or in a separate library. But I do not think that these features should be included in WxGeneric. It should be as it is, a simple library to generically construct widgets.
The next post
In the next post we will look at how to use WxGeneric. The impatient can have a look at the darcs repository and the documentation.
May 21, 2008 at 9:31 pm
[...] 21, 2008 As I posted earlier AutoForms has been reimplement in a new library called WxGeneric. In this post we look at using WxGeneric from a purely practical [...]
April 6, 2009 at 6:33 am
unfortunately the documentation link does not work
April 6, 2009 at 5:19 pm
Hi Andrew
I updated the documentation link. I also updated the darcs repository link, but I could not test it as code.haskell.org seems to be down.
/Mads
April 6, 2009 at 5:43 pm
Hi Andrew
I can reach code.haskell.org again, and the Darcs repository link I made 20 minutes ago works.
Thanks for reporting the problem.
Greetings,
Mads
April 7, 2009 at 6:08 am
Screenshots would also be awesome!
April 12, 2009 at 11:31 pm
Hi Don
Try looking at http://lindstroem.wordpress.com/2008/05/21/using-wxgeneric/ .
Also I think I will make a new post, where I will show, with pictures, that WxGeneric can do more than showing static structures. It can also show recursively defined structures, removning and adding widgets as need be.
Regards,
Mads