What is Partial Function Application?

November 19, 2012 Steve Hawley

I’m going to talk about Partial Function Application in F# and show how you can simulate that (to a degree) in C#.

Let’s start with a function to calculate quadratic of the form ax2 + bx + c:

let quadratic a b c x =    a * x * x + b * x + c

This is pretty straight-forward – it just rips through the math and you can see that it works:

> quadratic 4.0 3.0 3.0 0.0;;val it : float = 3.0> quadratic 4.0 3.0 3.0 1.0;;val it : float = 10.0> quadratic 4.0 3.0 3.0 2.0;;val it : float = 25.0

The cool thing is that you don’t have to pass all of the arguments in to quadratic.  If you leave off arguments from the end to the front, what you get back is a function that can be applied to the arguments that you left off.  What happens is that the arguments you do supply get bound to the parameter names, but the rest still need to be done.  I can rework my example to save some typing:

let q1 = quadratic 4.0 3.0 3.0
> q1 0.0;;val it : float = 3.0> q1 1.0;;val it : float = 10.0> q1 2.0;;val it : float = 25.0

Moreover, I can define other functions in terms of quadratic.  For example, one form of linear function is a quadratic with a = 0:

let linear = quadratic 0.0

Nifty.  Now how do we do this in C#?  To do this, you need to think about what’s happening.  When you invoke a function without its full complement of arguments, the compiler goes through an act called “binding” wherein the supplied argument values are permanently tied to the parameter names.  In Lisp or Scheme (and F# is a cousin of these languages), this is often done by creating an “environment” which is a collection of bounds symbols and their values.  We can do this by representing a function as a delegate (which contains an optional reference to a class) and using the class itself as the environment.

Here’s the quadratic code “ported” to C#:

public class Quadratic{    private double _a, _b, _c;    private Quadratic(double a, double b, double c)    {       _a = a;       _b = b;       _c = c;    }    private Quadratic(double a, double b) : this(a, b, 0.0) { }    private Quadratic(double a) : this(a, 0.0, 0.0) { }    public static double Value(double a, double b, double c, double x)    {       return a * x * x + b * x + c;    }    private double _f1(double x) { return Value(_a, _b, _c, x); }    public static Func<double, double> F(double a, double b, double c)    {       Quadratic q = new Quadratic(a, b, c);       return q._f1;    }    private double _f2(double c, double x) { return Value(_a, _b, c, x); }    public static Func<double, double, double> F(double a, double b)    {       Quadratic q = new Quadratic(a, b);       return q._f2;    }    private double _f3(double b, double c, double x) { return Value(_a, b, c, x); }    public static Func<double, double, double, double> F(double a)    {       Quadratic q = new Quadratic(a);       return q._f3;    }}

What I’ve done is hidden the environment for the function in a private constructor for the class Quadratic.  I implemented the actual quadratic function with the static method Value.  In the first flavor of F, I take 3 arguments and by newing up a Quadratic, I have bound the values into the environment.  _f1 only takes x as its argument and uses _a, _b, and _c from the environment to calculate the quadratic.  In every subsequent flavor of F, I drop an argument.

I’m not saying that this is what F# is actually doing under the hood.  There are other ways to get the same behavior, but they’re all fairly similar.  For example, the F# compiler could just be writing a new function on the fly with the bound values being constants in the IL.  What happens is still the same; it’s just that the individual IL instructions become the environment instead of a class object.  Similarly, the code above could have used lambda expressions instead of the _f functions and then the lambda expression would have captured the arguments instead of the class:

public static Func<double, double> F(double a, double b, double c){    return x => Value(a, b, c, x);}

Looking at the C# code, you should be asking yourself why on earth you would want to do this in C#.  You might want to keep in mind that class encapsulation is a way of representing closures rather than the day-to-day business logic of your application.  Another case is when you have the task of porting F# code to another platform.  In our managed version of dotImage, I made heavy use of partial function application in order to make it easier for me to write generic functions to operate on different pixel formats.  It made my code a lot easier to read, maintain, and debug.  When I ported this to Java in JoltImage, I could have written the code without using this notion.  I was sorely tempted since at present Java doesn’t have delegates or lambda expressions in the way that C# does.  Because of this, I made an private abstract base class that had the method I wanted to expose and then had a subclass for each pixel format that had a constructor that parameterized the environment.

About the Author

Steve Hawley

Steve was with Atalasoft from 2005 until 2015. He was responsible for the architecture and development of DotImage, and one of the masterminds behind Bacon Day. Steve has over 20 years of experience with companies like Bell Communications Research, Adobe Systems, Newfire, Presto Technologies.

Follow on Twitter More Content by Steve Hawley
Previous Article
Jargon
Jargon

Last blog, I wrote about using C# to get some of the benefits of F#...

Next Article
Don’t Do Eclipse Headless Builds Ever

We standardized on using Eclipse for Java development for a few reasons,...

Try any of our Imaging SDKs free for 30 days with Full Support

Download Now