Learn You a Haskell for Great Good! by Miran Lipovaca
Publisher: No Starch Press
I got my first exposure to Haskell back in 2003. At that years ACCU conference I attended a session by Simon Peyton Jones. Simon talked about meta-programming in Haskell. I remember that his presentation made an interesting contrast to all the C++ template craze of that year. Unfortunately, much of Simon's presentation went over my head at that time. Haskell has evolved since then and so has, hopefully, I as a programmer. That's why I turned to Learn You a Haskell for Great Good to get an idea of what the language has to offer.
Haskell is a purely-functional programming language. It's a fascinating programming model since the purpose of software is all about side-effects. So, what does a pure language bring? Like always, it's a trade-off. A pure functional language does make it easier to reason about code. At least in the general case, but there's another side of the functional coin; Given that Haskell also features lazy evaluation (expressions aren't evaluated until their value is needed) it's also non-trivial to reason about non-functional aspects of the program. For example, it's harder to reason about performance in the presence of lazy evaluation. A pure functional language also means you have to relearn and rethink basic operations like input/output, files and network access. Haskell isn't easy to learn. But it isn't hard because it's complicated (yes, I'm looking at you C++); it's hard because it differs radically from what you're used to and because it puts a lot of power in your hands.
My primary interest in Haskell is in its type system. I program in a variety of languages like Clojure, C#, Python, etc on a regular basis. These languages are all on different points in the static-dynamic typing continuum. Haskell, so much I knew up-front, is quite different. Haskell promises a type system that actually helps instead of hinders. So what does it look like? Well, I had to wait until chapter 3 to get a grasp of it. Haskell's type classes are nothing like ordinary object-oriented classes. Instead, I view a Haskell type class as a specification of capabilities. They're like an interface to your data. It's a mechanism that allows you to write generic functions. All you do is to specify type constraints on your functions. For example, you may specify that the type used as argument needs to define equality. Now all types that fulfill those constraints will be able to utilize your function. Of course, each type specifies itself what those required operations mean on its particular data (it's a variation of polymorphism). Oh, does it still sound object-oriented? It sure isn't. Since the type of every expression is known at compile-time, the type system will catch most errors. And, in contrast to OO, data and functions are orthogonal with type classes serving as their glue.
Let's take a short sidetrack now and reflect upon the relationship to more mainstream technologies. I started this blog post by recalling a decade old C++ conference. If you're familiar with C++, you'll find that Haskell's type classes have more in common with C++ templates than with normal classes. Remember, we're in compile-time wonderland, where I like to exercise as much of my programs as possible. A decade ago, C++ meta-programming was painful. A feature similar to type classes would fix the worst problems with meta-programming in C++. In fact, the programming model of Haskell's type classes is reminiscent of the dropped concepts proposal intended for C++ 11. It would be powerful, but probably requires a solid programming model designed from the ground-up.
So, back to the book. Learn You a Haskell for Great Good covers a lot of material. It starts out gently by introducing the basics like higher-order functions, pattern matching and lambdas. These first few chapters are easy if you have a functional programming background, preferably in a ML descendant like OCaml or F#. But the book soon picks-up the pace and goes into concepts that I only had a shallow understanding of. We get to learn about applicative functors and, of course, monads. These chapters, in contrast to the earlier parts, are conceptually more challenging. But if you follow along you'll soon have a grasp of the basics. It's all quite logical and consistent (after all, it's based on math).
The strength of the book is it's skillful blend of theory and practice. New concepts are introduced in small pieces and presented step by step in the interactive Haskell shell. That encourages you to experiment and play around with the expressions. When it comes to learning a programming language, there's nothing that beats an interactive environment. My only complaint is that I lacked more real-world examples.
Learn You a Haskell for Great Good is a great introduction to an exciting language. It's a book I'll probably return to. I just have to decide if I'll focus on really learning Haskell or if I pick some of my other language candidates (J, Pharo and Elixir all fight for my attention). A highly recommended read that gives you a new perspective on how programs may be written!
Reviewed January 2015