Who is my Community?

“Executive” Summary

This post is more of an op-ed piece than anything technically illuminating, and certainly not Haskell specific. Those not wishing to be exposed to a high level of pontification may prefer to pass. Similarly, those unused to my writing style may be disconcerted at just how many digressions I manage to fit into a short blog post. Imagine something like Steve Yegge, but without the wit, expertise or insight, and you shouldn’t be too far off. Again, please pass if this is an issue for you.

If you are a time-starved executive type who needs to cut to the content and ignore the crap, see immediately below.

tl;dr: We built something which might be of interest to others. Should we bother to make it accessible to others when it would make our own lives, and those of our existing community, harder?

wxHaskell – why bother?

I am the lead maintainer of wxHaskell, a Haskell binding for the wxWidgets library. As part of a coming push to make wxHaskell compatible with wxWidgets 2.9, we have done quite a bit of work which has raised questions as to the ‘best’ way forward in a number of areas.

As Open Source communities go, the Haskell community is probably a relative outlier in a number of ways which matter to an Open Source Haskell contributor:

  • It is relatively small;
  • Its members have an astonishingly wide range of abilities and interests;
  • It is incredibly good natured and helpful to all, pretty much regardless of level of ability.

The small size of the community means that many projects struggle to maintain a significant level of engagement over time. There are, I think, relatively few people interested in the nuts and bolts of maintaining a GUI binding, and this effort is split across several GUI bindings (Gtk2Hs and wxHaskell being probably the best supported, but with QTHaskell and HOC). There are good reasons for the split opinion on which GUI library to bind with, and I won’t explore them here.

Why not Gtk?

One aspect of wxHaskell which I hugely appreciate is that it works on the three main platforms: Linux and other unices; Windows and OS X, and delivers ‘native’ application look and feel without too much problem on all, and this is an attribute I’m determined we should keep.

In common with many programming languages, Haskell has an FFI binding which has no problem interfacing with libraries written in C, but cannot natively interface with libraries written in C++. There are very good reasons for this (basically that there is no way for anything other than the C++ compiler which originally compiled a C++ library to know how to call or link to the functions in that library – or more technically, every C++ compiler does name mangling differently).

This is probably the reason that GTK has become the default GUI binding for many non-mainstream languages. GTK may have <opinion-not-fact>a rather ugly approach to object-orientation</opinion-not-fact>, but all of its APIs are accessible in standard C, and it is therefore relatively straightforward to write a low-level GTK binding.

GTK is an outlier in the GUI world, however. Most GUI libraries are designed in object oriented fashion, using languages, like C++, which natively support object orientation. There are also good reasons for this: GUIs are <opinion-again> one of the few application areas </opinion-again> where classical object orientation is a very good way of expressing design (the other is designing libraries for classifying shapes, which seems to be a staple of OO tutorials, but not something for which I have seen an overwhelming demand in my professional life).

Wrapping C++ for beginners

Fortunately, it is very simple to make C++ code comprehensible to systems which only understand C. Suppose you have a class something like (borrowed from C++ Language Tutorial):

class CRectangle {
    int x, y;
  public:
    void set_values(int, int);
    int get_area() const;
};

It is straightforward to write a wrapper for the class, callable in C, which looks (if you ignore error checking etc.) something like:

extern "C" {
  void CRectangle_set_values(CRectangle* self, int x, int y) {
    self->set_values(x, y);
  }
  int CRectangle_get_area(CRectangle* self) {
    return self->get_area();
  }
}

You will notice that in each case, we pass around a pointer to the C++ object and use it to call the C++ function from within a function declared (with the “C” modifier) as being compatible with C calling and linker conventions.

Most of wxHaskell is wrapper code of this type. It’s not hard to write, but there is enough of it required that the writing soon becomes tedious and error prone. SWIG is designed to do this sort of thing, but it doesn’t have a Haskell backend, and when I started to work on one I quickly discovered that the documentation is a long way out of sync with SWIG itself, although the SWIG community is very helpful on the mailing lists. I may come back to a SWIG backend one day, but life is short!

That was a pretty long digression which was aimed at saying the what we have actually built is a C binding to wxWidgets. This is therefore just as accessible to most language FFIs out there as GTK, and would form a pretty good basis for a wxWidgets binding for many non-mainstream languages.

Standing on the shoulders of giants (and the not-so-giant)

Now, all of this good stuff is built on a wide range of Open Source code. Obviously the most important component is wxWidgets itself, but wxHaskell itself was forked from wxEiffel. We also use wx-config-win, a replacement for wx-config on Windows machines, and a project called wxC was forked some time back from wxEiffel (I think) to make a generic C wrapper.

In common with many Open Source projects, unfortunately many of these are moribund – the original contributors moved on and were never replaced, and so we end up with a fork or replace question. In most cases the answer to this is easy: fork – replace is almost always too costly. However Haskell is very productive indeed, which puts the question more finely in balance, and leads me (barring a few more digressions) to what I am really pondering.

How can I best serve ‘the community’ and what is that community anyway?

As I mentioned, right now we have a fairly complete C wrapper for wxWidgets. It builds as a DLL/shared library, and uses plain C headers, which means it could be used by pretty much any language.

There’s a barrier though. In order to make it as easy as possible for the Haskell community to set up and use wxHaskell, we have used a very Haskell-centric approach to building the library (Cabal, which is the standard way of distributing Haskell source libraries).

Unfortunately, I’m sure this would be a disincentive to anyone from, say, the Ocaml, Forth, Lisp or pretty much any other language community from using or contributing to the C wrapper (“waddya mean I need to download 200MB of Haskell Platform just to build a C library?”). I certainly know that I get discouraged when looking at a potentially interesting project only to discover that I need to locate 15 different packages before I even get to try to build it – an operation which is far from guaranteed to be successful with many projects.

So now I, or rather the wxHaskell community, recognise that we have a conflict of interest: we have built something which might be useful to many other groups (but we’re not sure if there is anyone out there who cares), but making life easier for those other groups will make life harder for our existing community, at least in the short term.

However, the other side of the calculation is that if other language communities get involved in contributing to the C binding, we get a larger community with a greater level of contrbution and engagement.

So we finally come to the point: is anyone out there interested in a C binding to wxWidgets, and if so, are they interested enough to want to help?

wxHaskell and wxWidgets 2.9

Those who follow the wxHaskell developer or users lists will know that over the last few months there has been a flurry of activity on wxHaskell, spurred on by Dave Tapley. I wanted to summarise what has been happening, and what stands in the way of a release supporting wxWidgets 2.9

<blatent-plug>Dave is working on wxHaskell with the agreement of his employer, Mentics Inc. I encourage any readers who have the opportunity to place business in Mentics’ direction to do so in appreciation of this generous donation of time and talent to the Haskell community.</blatent-plug>

Why wxWidgets 2.9?

Most Linux distributions currently supply wxWidgets 2.8.x libraries from their packaging systems, and Windows has the pre-built and readily installable wxPack containing wxWidgets 2.8.12, so why are we moving to an unstable release of wxWidgets?

There are many reasons, but two stand out in particular:

  • It is the future. wxWidgets 3.0 will be released from the 2.9 line, and provides major improvements. These include:
    • Much improved Unicode support.
    • Lots of new controls: ribbon bars, wxPropertyGrid, wxWebView, wxTreeListCtrl, wxRichToolTip, wxRichMessageDialog. Together, these simplify the creation of GUIs with a ‘modern’ look and feel.
    • The stc library (used by StyledTextControl) is now part of the main library build (as is SVG, which I would like to wrap for wxHaskell in the near future).
    • Support for 64bit OS X builds, which we have been unable to support on wxHaskell due to underlying lack of support in wxWidgets.
  • We need to clean up some legacy ‘cruft’ in the code. Daan originally wrote wxHaskell for wxWidgets 2.4.x, and things have moved forward a long way since then. This is an opportunity to remove deprecated functions and offer cleaner APIs.

What is changing?

The changes listed exist today in Dave’s development repository at DarcsDen, and will be mainlined in our master repository at code.haskell.org starting the coming weekend.

  • Newly wrapped classes
    • PropertyGrid, related helper types and sample code (Dave Tapley)
    • ListView (Dave Tapley)
  • Reinstated features
    • StyledTextCtrl (Dave Tapley)
    • OpenGL (Me)
    • Ability to use wxHaskell in GHCi (Dave Tapley)
  • Build system improvements
    • Some old Eiffel legacy code in the build system has been removed. Everything is now either C++ or Haskell (Eric Kow).
    • The C wrapper for wxWidgets has been moved into a separate project, wxC and built as a shared library (Dave Tapley).
    • Work to support OS X Lion (Eric and Alessandro Vermulen).
    • A Haskell native implementation of wx-config for use on Windows platforms. We are not sure if we will use this as yet – it is experimental (Eric).
  • Bugfixes and ‘build experience’ contributions from all of the above and several others , including Shelarcy, Maciek Makowski, Henning Thielemann, Peter Simons.

What is left to do before there is a release to Hackage?

Quite a bit!

The code in Dave’s repo is reasonably well tested on Linux (Ubuntu), but has currently received insufficient love on Windows or Mac. We will need it to work reliably on all three platforms before it can be released.

I think that the main blocker right now is probably determining the correct configuration for a Windows build. We have a couple of options here. We could develop Eric’s Haskell wx-config replacement so that it has been tested for a good subset of all possible wxWidgets build configurations, or we could fix wx-config-win to the same end. This has raised some philosophical questions on ‘Open Source and community’ which I am thinking of blogging on separately.

Most of all, when we have candidate builds ready, I hope that wxHaskell users will help out by trying to install the new version on as many machines as possible, so that we can be sure that we have everything working.