Rescuing Legacy Code by Extracting Pure Functions

After running a handful of Legacy Code Retreats I’ve had the chance to try a number of exercises related to rescuing legacy code. I’d like to share one that has met with very positive reactions from people: extracting pure functions. I use the term pure function to describe a function that only operates on local variables and parameters, but does not touch any state outside the function. No object fields, no global data. I have very little experience in functional programming, so I hope I use the term in a standard way.


This is a companion discussion topic for the original entry at http://blog.thecodewhisperer.com/permalink/rescuing-legacy-code-by-extracting-pure-functions

Sounds like a great experience to me!

I have had occasions to introduce a parameter, but because that parameter depended on an intermediate calculation earlier in the function, the caller can't pass the result of that calculation into the function. Result: changed behavior. I have an example of this, but I haven't yet done a screencast of it. I will, someday.

And yes, your hypothesis about Parameter Objects attracting the newly-extracted Pure Functions matches my experience so far.

I'm a fan of this technique and consider it very useful when trying to
eliminate a base class that turns out to be a lousy abstraction for its
children. It feels like the opposite of a Method Object to me, instead
of driving overdone procedural code into a cohesive object, you're
pushing over-coupled OO into something more functional.

Yes: I haven't experienced it yet, but I could see introducing a Method Object as an intermediate step towards pure functions. I might pull Method Objects out of a big-ass God class, then try to extract pure functions from within the Method Objects.

Love the write up and definitely interested in learning more on the subject of working with Legacy code. An often neglected but vital area of our field.

Screencasts for me are a magical learning tool. I always devore them and the lead time to grasp the concept and start using it in my day to day routine is minimal. So if you still have the energy to pursue it, I'd really appreciate it.

I ran into a similar issue recently. I have a legacy code base, and I want to extract pure functions from the code. The problem I was running into was that not all of the state could be extracted into either input parameters or output return values. For example, let's say you have a logger which runs in the middle of your "pure" function. Usually it isn't a big deal to leave a logger in your code, but sometimes you want to invoke your pure function without logging. I posed the question on StackOverflow, looking for answers. http://stackoverflow.com/qu...
I came up with a way to do this: add callback functions as parameters to your pure function. Any time you want to change state, instead, call a callback function to do so. In your production code, the callback would alter the state. If you're testing the code, the callback is NULL, and never called. I made a GitHub repo and made some examples in different code. https://github.com/daverobe...