From C++ to Haskell…
For the next undertaking, I wanted something radically different. Since the above mentioned languages are all – more or less – conceptually very close to C++, I had to look somewhere else: functional programming. At university I was exposed to the Lisp-dialect Scheme, which was ok, but I never got over the mountains of parentheses. Although I enjoyed the difference from the imperative and object-oriented approach. There are lots of options to consider: Go, Erlang, F#, ML, Scala, OCaml and so on. But nothing is as radical and uncompromising as Haskell in the pool of functional languages. So Haskell became my pick!
So far I read through Learn you a Haskell for Great Good a few months ago, but did not follow it up with exercises of my own in order to make what I learned stick. Nevertheless it was enough initial exposure to Haskell, to keep the language constantly in the back of my head. Recently I decided to be more serious about Haskell and start the path to become really fluent in it. Part of that endeavor is reading some recommended literature on the language. Enter…
I am now more than half way through G. Hutton’s book “Programming in Haskell” (2nd edition, from 2016) in the middle of functors, applicatives and monads. About 3000 lines of Haskell code I have written so far. If you don’t know Haskell and want some comparison with C++ and the like, you can easily multiply that number with four or five. Haskell is semantically so tremendously dense… I am genuinely impressed!
For example, this is generic quicksort in Haskell (works for int, bool, string… whatever):
Ignoring C++’s STL for the moment, I challenge you to write a comparable generic quicksort, that is as readable. This is not just some cherry-picked example. As an additional exercise to force my brain to think functionally, I am solving the tasks from Project Euler in C++ and Haskell. The Haskell versions are much shorter every time.
Ok, it is not all sunshine in Haskell-land. Run-time performance is only within 85% of C++ (from my experience so far) and Haskell is garbage-collected. That is almost a no-go for me, but the productivity gains and expressiveness gains are worth it in my opinion. Resulting binaries are comparable in size to C++ as long as you compile you Haskell code with options
-O2 -dynamic and strip the result.
At the time of writing, I am using ghc 8.2.2 as my Haskell-compiler of choice, which implements the most current language specification: Haskell2010. There is not much variety in terms of compilers. Haskell is pretty much a single compiler-implementation language. There are interpreters like HUGS. The performance of such interpreters is ok for small snippets of code and for typical REPL (read-evaluate-print-loop).
I plan to write more frequently about my adventure with Haskell and address my impressions on topics like separation of pure/side-effect-prone code, lazy evaluation, free concurrency and parallelism and the landscape of available libraries.