December was a busy month for me with not much time for blogging. It looks that January will be even more busy, but I want to write some posts I didn’t have time to finish for the last couple of months. I have some book reviews on my mind and today I will begin with Real World Haskell.
Real World Haskell – commonly referred to as RWH – was written by Bryan O’Sullivan, John Goerzen and Don Stewart and published in 2008 by O’Reilly. With 28 chapters on 670 pages it is the book about Haskell. There is no more comprehensive book on Haskell at this moment. The best thing is it is available on-line for free. I don’t like reading large amounts of text from a computer screen, so when I decided to learn Haskell 10 months ago I mailed my university’s library and asked if they could get the book for me. Three weeks later brand new copy of RWH was on my desk. Up till now I read chapters 1-11, 17 and 25 which is about half of the book. Perhaps a review should be based on reading the whole, but after over 300 pages I already have my opinion and I don’t think it will change much after reading remaining chapters.
The book assumes no prior knowledge of Haskell or functional programming. It starts off with simple, introductory topics and explains concepts of functional approach to programming. While the first examples of code are rather simple the book quickly moves to real-world applications (as the title rightly suggests). Aside from standard Haskell topics like lazy evaluation, typeclasses or monads, the book covers also parsing, databases, GUI programming, testing, profiling or interfacing with C. There are also many case studies. The good thing about the book is that chapters about particular technologies (that would be from 16 onwards) are self-contained and can be read in any order. On the other hand initial chapters seem to be a bit messy – they contain lots of valuable information scattered around in completely unexpected places.
While the book is a great source of information there are some reasons not to be happy with it. First of all I think that it is not suitable for most beginners. While RWH assumes no prior knowledge, the examples quickly get complicated and it might be hard to figure out what is really going on in the code. Authors often use top-down approach, that is they present a lot of code out of nowhere and then go into explaining what it does (this is the analytical approach). For that reason I had a lot of hard time with parsing described in chapter 10 and after reading the chapter twice I still don’t understand all of it. I think that in some cases bottom-up (a.k.a synthetic) approach to algorithm construction would be more suitable. This is of course very subjective – some people might be able to understand everything without problems. Anyway, the book is demanding and the reader should be prepared for it. Also, be prepared that chapters about more advanced technologies give mostly an overview and are not comprehensive treatment of the subject. After reading chapter about FFI I wasn’t able to write my own C bindings and only after reading the official FFI specification things became clear.
I was disappointed with the lack of discussion of GHC internals. I think it would be useful to explain things like thunks, WHNF as well as lazy evaluation model and possible performance issues related to it (memory leaks for example). There is one chapter about performance and profiling in general but it doesn’t go into details of how the compiler and runtime system works.
Speaking of the performance chapter, RWH is also affected by changes made to GHC since the book was published. Luckily this is not a major issue as almost all examples work as they should. Chapter about performance is seriously affected though. I wasn’t able to reproduce any of the presented results with GHC 7.4.2, but of course authors can’t be blamed for that. Also, one code snippet does not work because of changes made in GHC but again this is not a big problem.
I had a feeling that some basic concepts are not explained clearly enough. For example the book shows usage of
if instruction in place where a more experienced functional programmer would probably use pattern matching (page 30). This might be fine since at this point the reader was not yet introduced to pattern matching. The problem is that this is only clarified on page 207, way too late in my opinion, especially that patterns are introduced on page 50. I also had a feeling that currying was not explained clearly and stressed enough. Moreover the book does not mention the term “referential transparency” (might be a good thing to teach wannabe Haskell programmers some jargon they are likely to encounter) and from the comments on the web I noticed that people not familiar with the concept of “side effects” are confused by the book’s explanation of that term. I also found that omitting type signatures in some function definitions makes the code harder to understand. Finally, one note about editorial side of the book. The book uses different kinds of crosses, stars, paragraphs and other signs to denote footnotes. It looks as though editors have decided not to use the same mark twice which is a bit annoying for me, but this is of course very subjective and definitely not related to the quality of the book itself.
Although I complained that some concepts could have been explained in a different way I still think that RWH is a must-read for any serious Haskell programmer. Mostly because it gathers a lot of practical information in one place. I hope to find more time to finish reading it as I’m very curious about chapters on monads and monad transformers.