Thursday, March 7, 2013

On Functional Islands in Obejct Oriented Code

This post is a comment on some of how Brian Marick outlines how to embed functional code in a object oriented code base in his book "Functional Programming for the Object-Oriented Programmer". An excellent book for anybody moving into FP from OO, by the way. I definitely recommend it.

TL;DR

I feel that the best way to embed functional islands in an OO code base is to have certain classes be fully OO on the outside and as functional as you can get them on the inside. Doing so in a multi-paradigm language like C#, the bridging between the OO realm and the FP realm can become seamless.

Functional Islands


Brian uses a drawing like this one in his book to explain that functional code can live within an OO structure, and can be used by the OO code via a couple of bridges; one transforming an object graph to a data structure more suitable for the functional code, and one doing the opposite transformation. This bridging is done because functional code tends to work more on data than on objects - typically contained in general data structures like lists or sets. 

This makes sense; the OO world has one way of modeling and the FP world has another way. To move between them some bridging is needed. The book goes on to show an example of this, where some Java code calls into some Clojure code. But before and after the functional Clojure code runs, the bridging occurs. Each bridge is simply a Java method that does the required transformations; simple but tedious code.

I can sort of recognize this pattern from my own C# code, but only sort of. What I usually have when I embed functional code in otherwise OO C# code is that certain classes expose an OO interface to the rest of the code base, but are implemented in a functional style. To demonstrate this I've taken the example from Brians book and sketched in C#.  The rest of this post walks through that code.

Example

The example i: Given a number of courses that run either morning or afternoon, a fixed number of intructors that can teach any course, and a number of registrants that have wishes for which courses they want to attend find a solution.

First off here is the C# code for the OO strucutre Brian uses in his book:


just a few stupid classes - these should probably be better incapsulated, but that is not really the point here.

The solution I want to end up with should be an instance of this class:


To get there the CoursePlan class is used. This is the class that is implemented in a functional style - or to be honest a somwhat functional style: It represents its state as a couple of lists, and does it's work by applying functions to these lists. Moreover it uses functions that work lazily. That's functional. On the other hand is mutates the state of objects inside it lists. In other words it has side effects. Not so functional. All in all I thinks it's fair to say CoursePlan is implemented in a functional style.

To use CoursePlan I do this:


I just create a new CoursePlan and pass in a course list, registrant list and the number of instructors. Notice the CourseList and RegistrantList? -Those are domain specific collections. By which I mean domain objects like any other that happen to implement the domain notions of "a list of courses" and of "a list of registrants". Having such domain specific classes instead of List<Course> and List<Registrant> in my experience leads to cleaner OO code, and is something I usually advocate.

So where does the bridging from OO to FP go on? Well that's the point it's almost not there: The bridging is taken care of simply because the two domain specific collections - CourseList and RegistrantList - implement IEnumerable<Course> and IEnumerable<Registrant> respectively.

The code for CoursePlan is pretty trivial, but here you go anyway:


Conclusion

In conclusion I feel that the best way to embed functional islands in an OO code base is to have certain classes be fully OO on the outside and as functional as you can get them on the inside. Doing so  in a multi-paradigm language like C#, the bridging between the OO realm and the FP realm can become seamless.

2 comments:

  1. That seems reasonable. I've done something similar with Ruby code. There are a couple of things that you might lose out on if you take this style: 1) depending on your language, you lose the chance to write function-generating functions. 2) Unless you have your classes descend from a key-value associative structure (like Hash in Ruby), you lose the ability to add arbitrary (like intermediate) data to structures. (Some people wouldn't think that a disadvantage, I know.) I suppose it's also true that you lose the security of immutability, but I'm undecided how much that matters.

    ReplyDelete
    Replies
    1. C# is not a functional language. It's an OO language with a bit of FP bolted on IMO. -Bolted on in sensible and useful way, but bolted on nonetheless. This does limit how functional the code becomes. And you're right doing functions that generate other functions gets weird in C#, although you can have delegate types as return values.
      TBH I'm undecided on 2) - I guess in C# you could go in that direction with the dynamic expando objects. -But again I feel that easily gets weird in C#.
      The immutability OTOH I really miss in C#. -That's one of my main take aways from working with Scala.

      Delete