Pages

Thursday, October 4, 2012

Using the Partial Application Pattern in ColdFusion 10

The partial application pattern has been popular in JavaScript for some time now, Ben Alman has a great article on it: http://benalman.com/news/2012/09/partial-application-in-javascript/. While refactoring some particularly redundant code I decided to try this pattern in ColdFusion using the power of closures and the function datatype.

The Partial Pattern

Lets start by taking one of Ben's examples and converting it to ColdFusion. Minuse a few syntactical changes we could almost copy and paste his code into ColdFusion. Lets start of by looking at a simple add function:

Now lets say we use that function to add one to a few numbers:

Instead of passing the parameter one to each function call wouldn't it be nice to have a function called addOne that just adds one to whatever argument is passed in? Simple. We can just create a new, more specialized, function that returns the invocation of our add function that always passes one as its first parameter:

Thats great. What if we want to add other numbers? We'd have to create a separate function for each number. What if those numbers aren't always known when we are writing our code, are we going to write a million different utility functions? Of course not. We can take the concept of creating a specialized function step further using the function datatype and closures to create a partial application that will help us construct new helper functions on the fly:

Looking at the code there are a few important concepts to note. First look at how this new function returns a function, this is a new datatype on ColdFusion 10 so this code will not work in any version less than 10. Second, and most importantly, look at how this new function is a closure. When we invoke the makeAdder function the inner function that is returned has access to makeAdder's argument even after makeAdder is invoked.

Since the makeAdder function returns a function we need to set a variable equal to the makeAdder's result to use it. Once we do that the new function can be invoked just like any other function:

Real World Example

In my application I had a function that took a long list of arguments which was called multiple times with only a few of the arguments changing between each call. This created some ugly code that was getting to be a pain to maintain. Instead of calling this function multiple times passing in all the arguments each time I decided to use the partial application pattern to clean up some of my code. This is what my new partial function looked like:
Instead of having one function that has 7 arguments that is called multiple times I have one function that takes 5 arguments that is called once. This function returns another function that gets called with only 3 arguments:

When ColdFusion first got closures I was unable to make the mental connection to how I was using closures in the JavaScript code I was writing. Slowly I am starting to write my ColdFusion more like I write JavaScript.