Learning curve

My journey into Haskell started with a book by Miran Lipovańća titled "Learn You a Haskell for Great Good". The book is available online for free and I highly recommend it - the author does a great job explaining complicated concepts in a beginner-friendly way. While reading it, I tried writing simple programs in Haskell and it appeared to be very hard as if the compiler was inventing new rules on the way to make sure my code never compiles.

The book is an introduction to the language and after finishing it (and making those small programs compile) I realised that I still have no idea how to build anything in Haskell. Definitely not something that has configuration, logging or persistent state. I had no idea how to structure the code in a good way, when to use certain language features and when not to.

So I started a pet project, a personalised news feed delivered to the email address with data sources being RSS and Atom, to begin with. Yes, I know there are news readers and other tools that do this already. Later I may write a post describing the rationale for inventing the wheel, for now here are some keywords: private yet personalised reading list.

The first attempt was not great: it was both spaghetti-like and, at the same time, had a shape of a star with every module importing Types.hs, where the data model lived. I sensed the smell but didn't really know how to get rid of it.

Then I stumbled upon a talk by Jasper Van der Jeugt, titled "Getting things done in Haskell" and it was an eye-opener (thanks Jasper!). With the new energy I have gotten from the talk, I carry on implementing my pet project, this time with more success. After a couple of iterations of refactoring, the tiny code base started to have a much better shape. I'll make sure to share it when it's functionally complete and not too ugly.

Rant

I don't think this section is much news to anyone who's programmed in Haskell, most of the points have already been posted online by other fools.

Graphical syntax

There's widespread use or even abuse of graphical syntax for infix operators. I appreciate that in some case it may make the code look more concise and elegant. But most of the time they are just hard to google and impossible to pronounce. Okay, maybe not impossible but definitely hard.

Here's what I'm talking about:

atTag tag = deep (isElem >>> hasName tag)

text = getChildren >>> getText

getGuest2 = atTag "guest" >>>
  proc x -> do
    fname <- text <<< atTag "fname" -< x
    lname <- text <<< atTag "lname" -< x
    returnA -< Guest { firstName = fname, lastName = lname }

this is an example from the XML processing library HXT documentation. I count four different types of infix operators here. I think -> is not an infix operator but I'm actually not sure!

It is not unlikely I will change my mind on the usefulness of Arrows and Lens after learning more about them, we'll see.

Records

Haskell records seem nice at first, they definitely do after reading about them in a book. But after using records for longer than 10 minutes you may become disenchanted, for example, the following code does not compile:

data Person  = MkPerson  { personId :: Int, name :: String }
data Address = MkAddress { personId :: Int, address :: String }

because both Person and Address have a field with label personId. It can be worked around by a GHC extension DuplicateRecordFields. It's nice but sometimes requires hints to disambiguate record usages.

Here's another take on fixing the records. The author basically suggests using Lens instead which brings me back to the part of the rant on graphical syntax.

Libraries

Quality of the libraries varies. For my simple use case, I've explored libraries for XML processing and HTTP clients. In Java and Python world there are good libraries for everything and basic HTTP or XML processing tools are a part of the language's standard library. In Haskell, not so much: you get to choose between a small number of pet projects that sometimes look like they were abandoned soon after being published. People on Twitter came up with a word for it, thesis-ware.

I have another problem with Haskell libraries: documentation (or, rather, lack of thereof). Hspec, which is arguably not a library, is an example of Haskell software with good documentation: it has a website with a getting started guide, examples with different levels of complexity, links to additional resources. Otherwise, it's not uncommon for a Haskell package from Hackage to have very sparse documentation consisting of generated Haddock module structure with little to none explanation of what functions, data types and other components are supposed to do and how to use them together. I don't remember ever seeing a usage example in Haddock generated documentation.

Integrated development environments (IDEs)

Coming from the JVM world, I am spoiled by good IDEs. I like it when there's smart and fast auto-complete which actually understands the language. When the IDE looks up the documentation for me and doesn't ask me to re-generate hoogle database or perform another made-up action. When it's possible to navigate to the source code of the library function directly from its use.

Haskero screenshot
Visual Studio Code with Haskero plugin showing a tooltip for a library function 'filter', yet no documentation is displayed.

Full disclosure, I'm not a huge fan of using Vim or Emacs, maybe the grass is greener on the other side, but the experience that the best VS Code plugin gives me is limited to syntax highlighting, code formatting and showing compiler error messages inline.

Small things

The good stuff

It would be unfair to waste so much space on the rants without expressing at least a little gratitude to the good parts of the language.

I wanted to write more about Haskell tools, so here's another, more objective, post on Haskell tools.