From C++ to Haskell…
… is a potentially very entangled step to take. I’m not leaving C++ behind, far from it. Learning a new language “every year” never felt like the challenge I expected it to be. In the past I’ve looked at Vala, C#, Python, JavaScript, TypeScript, Java & Kotlin. For me the most useful appear to be Kotlin (the better Java), Python and TypeScript (the better JavaScript). These impressions greatly depend on the problem domain you have to address of course.
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.