Real-World Functional Programming (book review)

I had been reading Tomas Petricek’s blog for some time when he announced that he was going to be writing a book. I can’t remember when this announcement was made, and somehow the book seems to have taken a long time to come out, but Real-World Functional Programming (co-authored with Jon Skeet) was certainly worth the wait.

This book isn’t just a simple introduction to programming in F#; it’s an introductory text on functional programming covering the many reasons why it is time for this programming paradigm to finally be accepted by mainstream programmers. And it also contains much more…

The authors promote the idea of functional programming as a new way of solving problems, where ideas such as immutability and functions as values can be used to solve parts of a problem in data- and behaviour-centric ways. Two benefits of these ideas are that the concurrency may well become easier to extract from the solution, and it may be easier to unit test the resulting code. These are two issues that are currently receiving much debate in the programming community.

The functional examples are written in both F# and C#, and show how many of the features introduced in version 3 of C# allow a more declarative style of programming. The examples clearly demonstrate how many of the benefits of functional programming can be grasped by C# programmers. In particular, the book relates the use of LINQ in C# with the use of pipelining in F. Many of the examples show the brevity of the F# syntax which makes it the more attractive option for functional programming. The authors also demonstrate how easy it is to mix code in C# and F#, showing that it is may now be possible to write algorithm-centric code in F#, and more object-oriented code such as GUI code in C#. Along the way, there are some tricks for getting generics to behave in C#, and an interesting section that compares the type checking algorithms of the two languages.

The book doesn’t cover all of the syntax of F#, but describes the major parts. Indeed, the coverage of computational workflows, also known as monads, is probably the best that I have ever read. Later chapters of the book look at functional reactive programming, an interesting if somewhat esoteric theory that neatly matches the abilities of functional programming languages to express domain specific ideas with a declarative means of specifying graphical models.

There are also chapters on asynchronous and parallel programming, which emphasise the benefits of the functional style; the former contains a very interesting example of fetching data from a web service in order to visualise it via graphs. The chapter on reactive functional programming is preceded by one showing how easy it is to write compositional functional libraries. These chapters truly emphasise the benefits of the functional approach.

The book is fairly long at close to 600 pages, and in my opinion, there isn’t much that is wrong with it. The authors introduce the concepts layer by layer, with several sections telling you that more detail will be available in later chapters. Having done a fair amount of functional programming in the past, I found this stratum by stratum approach a little annoying to start with, but with every section containing lots of interesting observations there was little opportunity for skipping parts of the book. In the end, the richness of the observations outweighed my annoyance at the repetition. It would have been nice to have more discussion of functional data types, though there is a lot of material available elsewhere on this subject. The book also contained my pet bug-bear – the use of memorization to improve the performance of functional code without any discussion of how to avoid the memorization cache becoming a memory leak.

Overall, this is an amazingly good book that puts into words the many benefits of the functional paradigm, and shows that the F# programming language can embrace both the functional and object-oriented styles of programming. C# programmers, too, can gain something from this book, using it to understand the ideas behind LINQ and lambda expressions and why these have been incorporated into the language. I’m going to be re-reading it and working through the examples in more depth in the near future.