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.