Reflections After a Hard Day in Haskell GUI Land

My progress on my current project (FNIStash) is unsteady, but yesterday I decided the time was right to start putting together a rudimentary GUI as both a learning exercise and as a boost of motivation for moving the program along.  After working on getting a basic toy GUI for an entire day, I have absolutely nothing to show for it.  It was truly the most disheartening and disappointing interaction with the Haskell ecosystem that I have had so far.  Here are some of my impressions.

As a Windows User

Trying to navigate the Haskell ecosystem as a Win 7 user is like making a deposit at a bank in loose change.  Some banks will accommodate you and others will turn you away, but in either case you’ll get the feeling that the way you are doing things is fundamentally looked down upon.  In cases where you are accommodated, you usually have to jump through many hoops, such as installing specialized build environments like MINGW32 or cygwin (which themselves might require several different installers) and manually building cross-platform libraries.  After a lot of work, you’ll find you’re ready to install the package you wanted to install all along, only to have it break for who-knows-why.  A lot of libraries are just not as easy as “cabal install haskell-gui-support”

Cabal

Cabal is a frustratingly constraining tool.  Far too frequently I encountered packages that, when trying to install, would say installing this package will break a dozen others.  If not that, then I often would be notified that the dependencies could not be resolved.  If you decide that you don’t care that your other packages break and go ahead with the install, it’s a tossup as to whether or not the install will be successful, but oops, you just broke a dozen of your old packages already, so if it fails you have some cleaning up to do.  I’ve become pretty skilled at clearing out my cabal and ghc databases and invoking cabal install world to just bring my packages back to a self-consistent state after trying and failing to install a new package to explore.

For packages that leverage a cross platform library, this is frustraing but understandable.  Often this house of cards is built by taking C or C++ source meant for a Unix like build environment, installing it through MINGw32 (as the special Windows installation instructions tell you to do), then installing a package from cabal that brings in the Haskell wrappers.  It’s not pretty, but it’s kind of expected when pulling in functionality across platforms and across languages.

What I don’t understand is why cabal should ever have a problem with some packages breaking others or dependencies not being resolved.  Cabal knows what package I want to install, it knows what versions of its dependencies it needs, and those dependencies are freely available from hackage (as are their own dependencies).  You would think that this is a simple scenario with a straight forward solution – recurse and build all versions of everything as needed.  But for some reason, cabal does not allow side-by-side installation of different versions of packages.  If you have a package that requires a specific version of a dependency, you are effectively prevented from using any package that requires a different version.  The utility cabal-dev is available, which allows the set of packages to be sandboxed on a per project basis, but that is small consolation if you (like me) need to get out of hell on a single project.

Side-by-side installation of multiple versions is a known and demonstrated solution to dependency hell.  I alternate between blaming the community for not solving this problem and blaming myself for not understanding why it is so difficult.  Solutions like Haskell Platform seem to me to be treating the symptom and not the disease.

Haskell Community

The Haskell community is widely regarded as newb-friendly.  If you need newb help, the haskell IRC channel is just a click away, and in cases where I didn’t get help from the IRC channel or haskell cafe, I’ve simply selected a knowledgable member of the Haskell subreddit and messaged them directly.  No one has ever called me a newb or made me feel dumb for asking questions, even when the answer was staring me in the face in the docs and I just didn’t notice.  It’s a great community.

What has happened (albeit occasionally) is that I might get no response at all, and as my questions become more advanced and specific, the likelihood that my queries get lost in the void increases.  This is no different from any other language community.  However, the Haskell community is tiny compared to, say, Python, so it’s pretty easy to exhaust all avenues of help.  If you’re in the Haskell Windows community, it’s even smaller.

Desperation in Finding a GUI Package

In my search to find a viable GUI package, the only one that I had absolutely any success with was HGamer3d, and it’s probably not a coincidence that it is designed to work on Windows.  It was the only package that I was able to install successfully (without any headaches either), and it also had several example sources that worked effortlessly.  The problem is that is has next to nothing for documentation.  I tried modifying an example slightly only to have the executable fail on startup for unknown reasons.  Maybe I will revisit it in the near future, but I would prefer to not have to learn Ogre to decipher the HGamer3d source code.

What I wanted at the start of all of this was a GUI library or framework that supported DDS texture files.  By the end, I was willing to settle for anything that would successfully install and would display an image in any format.  So why not the web frameworks?  Yesod can’t resolve dependencies, happstack fails to load the network package (for which I found a work around online that, alas, doesn’t work), and snap fails to build the lens package due to a segfault in the generated code.  I’m sure any of these would work if I had the “right” set of packages installed, but this is not a viable solution (see above).  I can’t rip my environment apart every time I need something new.

wxHaskell is the most popular GUI toolset based on this reddit discussion, but I forgot to sacrifice a goat as step 0 of the installation process, so I had very little success with it.

Now

I feel pretty similar to the author of this reddit discussion, except I had even less success.  GLUT, GLFW, elm, reactive this, FRP that.  I feel as if I have looked at everything and found success in nothing.  Others work in Haskell GUIs all the time, so I know it is possible and that part of the blame lies on my side of the screen.

This experience has been a completely different kind of difficulty compared to learning the Haskell language.  List comprehension, immutable variables, monads, type classes…these are all well documented concepts with essentially no variability from case to case.  Read up long enough and eventually they click, and you are on your way.  The problem I face now is that I don’t know where to go from here.

16 thoughts on “Reflections After a Hard Day in Haskell GUI Land

  1. I certainly feel your pain. I’ve managed to get a bit of GLUT working on windows by extreme luck. Most frustrating though is that I have never been able to get MySQL support compiled on Win 7. It either can’t find the mysql header/lib, or some other script fails for unknown reasons, and no matter what I tried I could not get it working. I can go without a GUI, but I can’t go without database support.

  2. > Solutions like Haskell Platform seem to me to be treating the symptom and not the disease.

    The Haskell Platform isn’t aimed at solving package management. It is aimed at specifying a core set of packages every decent Haskell installation should provide. I.e. a standard, comprehensive library.

    Regarding cabal, the problem is that cabal uses a single, global namespace by default for packages. This must be kept consistent. cabal-dev really is a solution, in that it allows per-project scoped namespaces. It is hard to conceive of other solutions, that don’t involve introducing first class packages into the language itself.

    • My understanding of the Haskell platform is that part of what it offers is that the packages it contains are verified to play nice with each other. This is the point I was trying to make in the original post – that there is an investigative effort to try to beat dependency hell before it arises.

  3. Hi,

    oh I know your feelings – been there a lot.
    While I cannot give you a solution to your problem as is I can tell you what I do.

    1. I use Ubuntu – no I’m not a NIXer (not at all) but I installed this in a VM just for Haskell – if I screw (Haskell) up – my clean system is just a rollback of my saved VM-image away (much faster then dealing with ghc-pkg)
    2. I (try to) use cabal-dev – yes it’s slow at first but it saves you a lot (remember NOT to cabal install cabal-dev but to use the git-version here: https://github.com/creswick/cabal-dev)
    3. even on windows “cabal install xyz –constraint “whatever installed” is really your friend (network, directory, etc. comes to mind -everything you know you have but needs those pesky MinGW shit that will fail anyway :D)
    4. There is no satisfactory UI package for windows – had some success with Gtk2Hs/Glade (http://projects.haskell.org/gtk2hs/docs/tutorial/glade/) but it feels like the old C++ / VB 6.0 times … don’t wanna go there any more
    5. The rescue might be to move to Html/Js – for example with Snap and Fay (https://github.com/faylang/fay/wiki) – with the “constraint” trick you should be able to install both on windows (maybe with a fresh Haskell Platform) without a problem – yeah I know: like picking out your eyes with all that JS and FFI things)
    6. There is a great (if not as powerful) good alternative to Haskell you can use just fine on Windows (and NIX/MAC): F# – the community is just as fine (I think there is a big overlap) and it just runs out of the box without any cabal-like hell (ok there are some minor issues with Nuget but nothing just like this) – while not Haskell (not even pure or lazy) – F# has a similar syntax (ML) and you can translate most things without much, but of course there are no type-classes and of course nothing of the other magic stuff we love in Haskell – BUT it is based on .NET and there you have everything a Web/UI programmer needs – images, network, web, ui, … a piece of cake.

    PS: I needed a machine to solve your Captcha … so maybe my comment was not so smart after all 😀

  4. Well, what can I say? I think the problem is, that you are trying to do serious work on a toy/consumer operating system.
    It’s like complaining why engineering a car in AutoCAD is so hard to do on the iPad.

    Either you are being serious, and want to do actual work, in which case you choose Linux or BSD or another full operating system.
    Or you are a consumer, toying around, consuming “content”, with your brain off… Then you can use Windows or OS X or Ubuntu.

  5. Thanks for the write up. I use haskell on osx and linux for my day job and wrestle with improving the support on win7 in my spare time. I send patches when I can fix things and try to remind folks to test on windows otherwise.

    As others have mentioned, cabal-dev is crucial.

    What type of GUI do you want to build? A generic application or something that has an opengl context and renders things that way? I see you mentioned GLFW, so perhaps you want to do graphics?

    If so, look at GLFW-b (yes the b matters) and OpenGL. I have some examples that should work (please file a bug report if they don’t work on your system).
    https://github.com/dagit/nehe-tuts

    It’s also on hackage by the same name.

    If you’re looking for a different type of GUI application then I fear you are out of luck at the moment.

    Feel free to contact me in #haskell (lispy) or on reddit or by email or whatever. I see the current paucity of GUI support as something that needs to be addressed, badly. There have been efforts and task forces assembled in the past, but the reality is that until some experienced haskeller with too much free time bites the bullet and does the job right we’ll continue to be in this state.

    • What I’m looking to build is essentially an image grid. Each cell of the grid has an image representing an item, and when users roll over some more information about the item is presented. There would also be some simple search functionality to find new items and add them to the grid. I also need to update files locally based on what the user does in the UI.

      My latest venture was to try ji to do basic browser manipulations for a GUI, but I’ve been jumping through hoops on that as well. I believe ji successfully installs, but the bundled examples don’t. I get failures of undefined references in the network package. I’ve tried a number of different network package versions, as well as some path manipulation I found online, but I’ve just about exhausted my options. I wonder if part of the problem is that these ji examples use snap, which says on its site that is it for Unix systems. Maybe it’s not snap but the network package on windows itself.

      • I built snap on windows with ghc last night so I know that can work. What is my setup? I’m glad you asked 🙂

        ghc 7.6.1 (without the haskell platform, 32bit version, the 64bit release isn’t able to build everything)
        gcc 4.5.2 (this came with my mingw install, which means I’ve had to make sure it’s in my PATH)
        Windows 7 64bit
        cabal version 1.16.0.1
        cabal-dev version 0.9.1

        Specifically I was able to use cabal-dev to install hakyll which has snap as a dependency. Having the platform would only be an issue if cabal is trying to use the wrong version of network (but that shouldn’t be your problem here).

        Don’t forget to ‘cabal update’ regularly.

        I hope that helps!

        • I really appreciate the tips, but I fear my patience has been exhausted. I simply cannot devote entire days of my weekend to resolving issues like these. When I have free time, I need to make progress on my hobby projects. I’m used to struggling with Haskell in my learning process, but these kinds of issues of not being quite sure what the problem is, and more or less blindly trying different combinations of tool versions….well, it’s the same reason I stopped using Linux on my primary personal machine after 5 or so years.

          Maybe your solution will work for me (and I might indeed try it), but given the sheer number of packages I’ve tried and failed to install, I’m not hopeful about success in the future. A number of folks have recommended F#, so I’ll be looking at that. I expect I will miss the Haskell purity and other neat features of the language if I choose to switch, but if it just works and I can use it to get stuff done while still exploring the functional paradigm, I’ll probably consider it a net gain.

          • I can empathize with that. I’m frequently turned off by how hard it is to get started with things. I simply refuse to use anything haskell that involves gtk2hs.

            If you decide to scratch this itch sometime in the future, maybe I can help you.

  6. Evi1M4chine’s comments are terribly short-sided and almost trollbait but I will bite. I don’t think that as a majority of Windows users that we’re opposed to using POSIX based system if available. I do love me some FreeBSD and OpenIndiana. The simple matter is that we may be hamstrung for those of us who are trying to get Haskell adopted into an enterprise environment. Toy operating system or not, it’s what is used in business; often it has to be brought in on small non crucial projects before it can be targeted for the large tier 1 deployments. At that point it should be a win-win since Haskell is so well suited to operate on those platforms.

    Maybe this could be approached from a different way, likely no easier since the resources for Haskell are extremely finite, especially in the Windows platform arena. I don’t recall exactly why GHC cannot be cross-compiled, but if that were possible then there could be a better solution. Perhaps it doesn’t have to be a one-for all cross compilation works everywhere, but if it were possible to focus on the bits needed to go from POSIX to Win32x64 then maybe it’ll be easier.

    I’ve also mentioned in a post on Reddit that perhaps the solution would be to have a dependency resolution tool that was specific to windows, as cabal is to POSIX, something like wabal for Win32. Basically something that can resolve the installed packages in a windows environment since the heir of the two are so different. Would probably be something similar to Maven *shudder*. Cabal-sandbox could possibly fill this role when it is out.

    • I don’t know how, myself. If you are getting emails like that there should be an unsubscribe link in the email itself. I’ll help if I can but this is the solution I find on Google for this problem.

  7. Hi,

    since I had the same Problems until recently, i figured out that FP Complete’s stack ( https://www.fpcomplete.com/blog/2015/06/stack-0-1-release ) seems to be my best solution for the cabal hell problem (on linux so far, but trying to install haskell platform with the GLUT binaries and using stack for the work seems to look like a solution). As for the GUI problem… I want to try some some web GUI stuff with haskell, but there is nothing specific in my head right now (maybe threepenny gui or snap+HTML5? stopped haskelling for a little rusting right now).
    Most of the time you get to see new cool stuff at http://planet.haskell.org/ for these kind of things.
    Hope that helps.

Leave a Reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

*
= 15 multiplied by 4