Eric Lippert's blog

Main menu

Post navigation

Functional style follow-up

Thanks to everyone who came out to my beginner talk on using functional style in C# on Wednesday. I had a great time and we had a capacity crowd. The video will be posted in a couple of weeks; I’ll put up a link when I have it.

A number of people asked questions that we did not have time to get to:

What is the advantage of using C# over a functional language like F#? How would you choose one or the other for a new project?

This is a bit of a “which is better, a gorilla or a shark?” questions, but I’ll give it a shot.

C# is primarily an OO language which supports programming in a functional style. F# is primarily a functional language which supports programming in an OO style. They’re both great languages; which I would choose for a given task would depend on factors like how familiar is the team with the given language, how much code do we have in one or the other language already, and so on. Both are good general-purpose programming languages. F# tends to be used in domains that have a lot of scientific or financial computations.

Can you recommend some good books related to C# functional programming?

“Real World Functional Programming” by Tomas Petricek and Jon Skeet is quite good. You can find some of the tutorial material from this book online here. It is very pragmatic.

A very advanced book I like on functional programming is Chris Okasaki’s book “Purely Functional Data Structures”. You should have a basic grasp of the ML language before you try to read this book. It is very academic.

How does functional programming work when interacting with databases?

When querying a database, functional programming works extraordinarily well. LINQ is entirely based on the idea of constructing immutable query objects that can be turned into efficient database queries. (I only showed “in memory” LINQ examples, but it works against databases as well.)

Things get a little more difficult when you consider database updates. Updating a database is a side effect on a massive amount of external state, and so very non-functional-style. The key to doing database updates in functional style is to take a more relaxed view of functional languages. Rather than saying “I’m going to eliminate all mutations and all statefulness”, rather say “I’m going to use functional style to make mutations and statefulness apparent and obvious so that I can understand them.”

What are some issues involving casting, interfaces and mutability?

A common technique for making a return value seem immutable is to have a method that returns IEnumerable<int>, but actually return an int[]. The developer reasons that the caller cannot mutate the array because IEnumerable<int> exposes no mutation methods, and therefore they can hand out the same array over and over. However nothing is stopping the caller from casting the sequence back to an array. Now, you can easily say that if it hurts when you do that, don’t do that. But I would rather hand out an ReadOnlyCollection<int> or the like, that wraps the mutable class rather than casting it.

Now, read-only collections have problems of their own. The underlying collection is still mutable, and if you mutate it then all the code using the read-only wrapper will see the change!

My preferred solution is to use immutable collections and builders. Use the builder when you need a mutable collection, and return the immutable collection. Immutable collections truly are immutable; they are not wrappers around something mutable.

Are functional programming and OOP here to stay? Or will one win over the other?

These are both very successful programming styles with a long history and bright futures. I see them moving together; many languages now have both OOP and functional features. C#, F#, OCaml, Scala, JavaScript and many more.

I think your paragraph on casting and mutability doesn’t mention the most important thing. For most people, it’s easy to think that allowing the client to cast your object back to something you didn’t return (e.g. the underlying array), or fiddle with the internals, is just the same as clients that copy the contents of the immutable structure into a new mutable structure, in C# for example simply calling ToList or ToArray. Both methods allow you to alter the data that was returned from the function.

However, I think the crucial point here, that you haven’t mentioned, is that with true immutability, a function can return the same immutable object to multiple clients and _guarantee_ that one client will not affect that object and adversely affect other clients. If one client decides to copy the contents into a list and mess around with it, that’s their problem, but crucially – no-one elses problem! This is clearly different to casting the object and messing with the internals, as that will affect all clients.