Real World Functional Programming: Book Review
The Book
Real World Functional Programming by Tomas Petricek with Jon Skeet (corresponding website)
The Review
What did I learn?
-
I’ve worked with C# 3.0 since around July 2008 so I had a bit of experience using some of the functional features in C# before picking up this book. I therefore found it very interesting to read about the history of lambda and the different functional languages and how they came into being. Having this as an opening chapter was a nice way to introduce the functional approach to programming.
-
Immutable state is one of the key ideas in functional programming - this reminded me of a Joe Armstrong video I watched last year where he spoke of his reduced need to use a debugger when coding Erlang due to the fact that there was only one place where state could have been set rather than several as is the case with a more imperative approach. We have been trying to code with immutable state in mind in our coding dojos and while it takes a bit more thinking up front, the code is much easier to read when written that way.
-
Separating the operations from the data is important for allowing us to write code that can be parallelised, focusing on what to do to the data rather than how to do it. Sadek Drobi has a nice illustration of what he calls mosquito programming vs functional programming on page 14 of the slides of his QCon presentation. It describes this idea quite nicely.
-
A cool technique that Phil taught me when reading language related books is to have the PDF of the book on one side of the screen and the REPL (in this case F# interactive) on the other side so that you can try out the examples in real time. The book encourages this approach and all the examples follow on from previous ones which I think works quite well for gradually introducing concepts.
-
Functions are types in functional programming - I have had a bit of exposure to this idea with Funcs in C# but partial function application is certainly a new concept to me. I can certainly see the value in this although it took me a while to get used to the idea. I am intrigued as to where we should use a functional approach and where an OO approach when working in C#. I think both have a place in well written code.
-
F#'s implicit static typing is one of my favourite things about the language - you get safety at compile time but you don’t waste a lot of code writing in type information that the compiler should be able to work out for you. It has the strongest type inference of any language that I’ve worked with and I thought it was quite nice that it was able to work stuff out for me instead of me having to type it all out.
-
I really like the idea of option types which I first learnt about from the book. Having the ability to explicitly define when a query hasn’t worked is far superior to having to do null checks in our code or the various strategies we use to get around this.
-
I thought it was cool that in the early chapters the focus with the F# code is to provide examples that you can just get running straight away instead of having to worry about the need to structure your code in a maintainable way. After I had a reasonable grasp of this then the chapter about using record types to structure code in an OO way come up. I still prefer the C# style of structuring code in objects - it just feels more natural to me at the moment and manages the complexity more easily. It is quite easy to switch between the two styles using features like member augmentation so I think it’s probably possible to mix the two styles quite easily.
-
We can use modules to make F# functions which don’t fit onto any class available from C# code. The code is not as clean as if we were writing just for it to be used by other F# code but it’s not too bad: ~ocaml module Tests = let WithIncome (f:Func<_, _>) client = { client with Income = f.Invoke(client.Income) } ~ We can then call this in our C# code like so: ~csharp Tests.WithIncome(income => income + 5000, client); ~ Dave Cameron has written more about this.
-
Although I studied data structures at university I don’t really pay a great deal of attention to them in terms of performance normally so it was interesting to see the massive performance hit that you take when appending a value to the end of an F# list compared to adding it to the beginning. F# uses linked lists so if we want to add something to the end then there is a lot of recursion involved to do that which is quite costly. In terms of big O notation we go from O(N) where N is the number of elements to append to O(N*M) in terms of performance.
-
Chapter 13 is about parallel processing of data for which I found I needed to download the Microsoft Parallel Extensions to .NET Framework 3.5, June 2008 Community Technology Preview and then add a reference to 'C:\Program Files\Microsoft Parallel Extensions Jun08 CTP\System.Threading.dll' in order to make use of those features.
-
The author provides a nice introduction to continuations and how you can make use of them in F# by using continuation passing style. I’m intrigued as to how we can make use of these in our code - we do a bit already by making use of callbacks which get fired at a later point in our code - but from what I’ve read it sounds like we should be able to do even more especially when writing web applications.
-
Asynchronous workflows are also made very accessible in this book - I had previously struggled a bit with them but the author covers the various API methods available to you and then explains what is going on behind the syntactic sugar that F# provides. I have made some use of these in the little twitter appication that I’ve been working on now and again.
In Summary
I really enjoyed reading this book - it’s my first real foray into the world of functional programming since university and I think I understand the functional approach to programming much better than I did back then from reading this book.
It takes an approach of introducing various functional programming concepts before showing examples of where that concept might come in useful when coding. It’s also particularly useful that examples are shown in C# and F# as this made it much easier for me to understand what the F# code was doing by comparing it with the code in a more familiar language.
I’d certainly recommend this to any .NET developers curious about learning how to apply ideas derived from functional programming to their C# code and indeed to any developers looking to start out learning about functional programming.
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.