Showing posts with label Partial Application. Show all posts
Showing posts with label Partial Application. Show all posts

Tuesday, July 1, 2014

Partial Partial Application

"Partial Application" (PA) means applying a function to only part of its arguments, and getting back a function which can take in the remaining ones. This post is about it and what I like to call "Partial Partial Application" -  meaning the resulting function can do partial application on its own, as well.

In a previous blog-post I wrote about "currying", a related concept. I posted that currying is the process of implementing a multi-argument function as a combination of single-argument functions, and calls to them. I'll discuss the difference and relationship of Partial Application and Currying, briefly.

Partial Application is something your program can do. "Currying" is something you, or your compiler or interpreter does. So PA seems like a  more straightforward concept to implement. And yes, there is an accompanying code-file that does it for you.

Let's start by asking:  If we had an implementation of the function 'applyPartially()' or applyP() for short, how would we use it? Let's write some test-cases! Ah, this is Test-Driven-Programming, we write the test-cases first?  Well maybe something like that. But let's start by writing the function applyP(), a 'dummy' version of it first. That dummy version says something about what it should do when it grows up, what kind of arguments it expects etc.

  function applyP (baseFunction, a, b, c, d, e)
  { 
   /**  ... NOT READY   
    Return a function that is like the argument 
    'aFunction' except that its leading arguments 
    will be "fixed" to be those given by the rest 
    of MY arguments. So, my result is a function
    which will (typically) take FEWER arguments 
    than my 1st argument, 'aFunction'.  
    */
   ...
  }

The 1st argument  of applyP( ) is called  baseFunction because the result of applyP() will be  derived  from it.

Now let's write one test for it:

 function f2(x,y)
 {return x + y.
 } 
 var f2b     =  applyP (f2, 1);
 ok (f2b (2) == 3);

Above we partially apply f2 with '1' as the fixed value of its first argument, and get a function f2b as the result.  Then we call f2b() passing only one argument '2' to it. Then verify that the result is 3 with our simple test-utility function 'ok()'. There, almost done. Should we go further? No, unless we can answer the following question:

What is it good for? Absolutely nothing? No. Partial Application is good whenever some arguments of a function come from a small fixed set. That usually means you will be calling the function many times with the same values from that fixed set. In such a case it makes sense to partially apply the function to those frequently used values. That will give you new functions that are simpler to call and easier to understand. They will be simpler because they take fewer arguments. They will be easier to understand because they can be given more meaningful names.

A typical example is any function that takes a boolean as one of its arguments, indicating a caller-preference of some kind.  Example:

  function runTest (haltOnError, testCase)
  { /* Run the test and if 1st argument is true
       and test-case fails, throw an error. If
       1st arg is false just return a boolean
       telling whether the test succeeded or not.
     */
    ...
  }

Now if you call runTest() many times,  sometimes with true,  sometime with false,  it might be a good idea to refactor it into two single-argument functions, by using  Partial Application:

   var runTestHalt   =  applyP (true,  aTestCase);
   var runTestNoHalt =  applyP (false, aTestCase);
   ...
   runTestHalt (myTestCase);
   //   runTestNoHalt (myTestCase);

The new partially applied functions are easier to understand because their names can express more about their semantics, because the semantics is simply simpler.There are fewer or no IF-THEN conditions you need to understand.  If you instead use the original test-function, your code would look like this:

   runTest (false, myTestCase) ;

Looking at the runTest() -call above it's not clear at all what is the meaning of the first argument. We can see it is false, but what does that MEAN?  It's hard to remember, takes some effort to look it up, and easy to pass a wrong value to it. Maybe you changed its meaning, and forgot to change some places where it was already called. When the error hits the fan in production, start debugging.

The First Rule of O-O Programmers:  Beware of IF-THEN !

In the accompanying code-file I provide an implementation of ClassCloud.applyP() which does partial-application for you. More than that, it returns functions that can successively partially apply themselves, to further arguments. Here's an excerpt from the unit-tests inside the code-file that show how it can be used:

   function f2 (x,y){return x + y}

   ok (applyP(f2, 1, 2)          == 3);
   ok (applyP(f2, 1   ) (2)      == 3);

   ok (applyP(f2      ) (1) (2)  == 3);
   ok (applyP(f2      ) (1,2)    == 3);


The last two tests above are interesting because they show that we can do partial application by providing ZERO arguments to fix, even though the function really needs more to calculate its value. Why would we do partial application with zero fixed arguments?  The last two lines  give us the clue: applyP(f2) returns a function that can be called exactly like its argument-function f2:
 
   ok ( applyP (f2) (1, 2) === f2 (1, 2) );

So it can do the same thing. But, it can also do MORE:  It can apply  ITS arguments partially, in separate calls as shown above and here again, still returning the same result as f2:

   ok ( applyP (f2) (1)(2) === f2 (1, 2));

We could say that applyP(f2) is not just a different version of f2(), it is a BETTER version of it. It can do everything  f2()does, and then some:  It can take its arguments incrementally.

applyP() as shown by above examples does partial application. But depending on how many arguments you give it, there may be more  partial application left you can do with its result.  Hence the title of this blog-post: Partial Partial Application. The results of applyP() can take care of the further rounds of partial application themselves, and they can do that in multiple stages as well - partially. applyP() can do partial application partially, or fully.


So how is Partial Application related to currying?  My previous blog-post was about currying. In that post I showed  how a function for calculating  max. of two numbers could be implemented in the "curried form" as two single-argument functions, one inside the other, the inner function returned as the result of the outer one:

  function max(a)
  { return maxB;
    function maxB (b)
    { return a < b ? b : a;
    }
  }

Note that the above function is not doing "currying". It is the result of you (or me) having done it. Making your compiler do it automatically is possible but a lot of work; it basically means implementing your own PL. Some PLs do it for you.  Whereas creating a function like applyP() should be within the realm of the practical, as shown by the accompanying, rather small file of JavaScript.

If you look at that code you will see that applyP()is mostly implemented by applyPBasic()which contains AND RETURNS the inner function newFunk(). That is basically the curried form shown for max() above. Currying is the way to implement Partial Application!

There's one more thing to know about ClassCloud.applyP():  It relies on the number of declared arguments of the base-function. If you use it with functions that rely on varying number of arguments, your results might vary (pun intended!). If you call it with more than the declared number of arguments you get an error, which is useful for error-checking. It checks that your assumptions about how many arguments a function takes are correct.  

You can copy the MIT-licensed implementation of applyP() including its tests from http://panuviljamaablog.blogspot.com/2014/07/classcloudapplypjs.html .


 © 2014 Panu Viljamaa. All rights reserved


Monday, March 10, 2014

Objects vs. Functions round 1: Currying vs. Instantiation

This article is about the difference between two Design Patterns: "FP Currying"  and "OO Instantiation". This is NOT about comparing the benefits of different programming languages, Object-Oriented, or Functional. We will use JavaScript examples to illustrate both patterns.

CAVEAT:  We will use the term "Currying" loosely here, to mean how we  would implement "something like it" in JavaScript.  It seems the proper definition of currying is calling a function with a subset of its arguments, and then getting back a function that has the previously given arguments fixed to the values you gave them.  The proper term for what we do below is "Partial Application"  meaning you pass in a function + some of its arguments into a function that returns a function where the given arguments have been fixed to values you gave.  You can read detailed explanation of the difference between currying and partial application here

It is often said the defining characteristic of Functional Programming (FP) is "Referential Transparency", or "immutability". But there is no reason why  OO "objects" can't be immutable.  And all FP languages must more or less allow things to "mutate", because they must deal with input-output in some fashion. A function that returns some data from the user most likely will return a different result the next time you call it.

For purposes of comparing FP and OO styles of programming I'd say the main difference is this:   In FP you create and call individual functions (which can return other functions).  In OO you create groups of functions called Classes which you then "instantiate" into Objects.


A well-known feature of FP is "currying" which loosely speaking means you can "fix" some of the arguments of a function to specific values to get another simpler function where those arguments will have the fixed values you gave. This means you don't need to re-enter that same value again and again.  "Currying" (or more properly "partial application") could be used in JavaScript  as follows:  

 function multiply (aNumber1, aNumber2){...}  
 var multiplyBy2 = curry(multiply, 2);
 var six         = multiplyBy2(3);

The benefit is that if you need to  multiply many different numbers by two you no longer need to pass both numbers as arguments of each call, one is enough. As mentioned the above is more "partial application" than "currying". But both serve the same purpose: Getting a simpler function out of a more complex one, by fixing some of the argument-values. I offer this characterization of the subtle difference between the two: "Currying is automated Partial Application"


So is there a way to achieve similar benefits with OO?  Yes. It is called instantiation. You define a "class" with a set of methods and a set of data and then "instantiate" it:

 function Multiplier () {...}    

 Multiplier.prototype.multiply = function multiply () {...}
 var multiplier2 =  new  Multiplier (2);
 var six         =  multiplier2.multiply(3);

Above  Multiplier  is the class,  multiplier2 its instance.

Based on the above examples it would seem currying is somewhat simpler. Fewer lines are needed. But what if you are looking for a solution that handles other numbers besides 2 as well?  The situation changes.

A Class is a group of functions parameterized  by the data defined for that class.   Therefore we can easily extend that group and add more functions or 'methods' to our class, to handle other calculations. So let's give our function/class a more general name, and  add methods for  different calculations:

 function Calc () {... }
 Calc.prototype.multiply = function () {...} 
 Calc.prototype.divide   = function () {...} 
 Calc.prototype.add      = function () {...} 
 Calc.prototype.subtract = function () {...} 
 Calc.prototype.raisedTo = function () {...} 

Then at runtime we can instantiate that class, with any number we want:

 var calcWith2 = new Calc (2); 

Feels a bit like currying, right?  If  we use traditional currying instead to create  multiple functions with a fixed parameter 2,  we  would write thus:

 var multiplyBy2 = curry(multiply, 2);
 ...
 var raisedTo2   = curry(raisedTo, 2);


Now imagine you need to handle other number as well: 3, 4, 5 , 99, etc.  What's so special about number 2 anyway?  Doing that by currying you need to apply currying to each function for each number we want to use as the fixed parameter:

 var multiplyBy3  = curry (multiply, 3);
 ...
 var raisedTo3    = curry (raisedTo, 3);

 var multiplyBy4  = curry (multiply, 4);
 ...
 var raisedTo4    = curry (raisedTo, 4);

 var multiplyBy5  = curry (multiply, 5);
 ...
 var raisedTo5    = curry (raisedTo, 5);

 ...

 var multiplyBy9  = curry (multiply, 9);
 ... 
 var raisedTo9    = curry (raisedTo, 9);



Using the OO -style we only need to write:

 var calcWith3 = new Calc (3);
 var calcWith4 = new Calc (4);
 var calcWith5 = new Calc (5);
  ...

With OO-instantiation we reuse the same parameter, say 4, and get a version of all  our math-functions, with a single call to instantiate the class Calc.  We don't need to re-curry all our methods for all numbers we need, 3,4, ... 99.  The advantage OO has is that the fixed  parameter 4 can be shared by ALL methods of the object-instance, by making a single call which creates that instance.

This benefit is not accidental.  It is a direct consequence of a defining feature of Object-Orientation: All functions ('methods') of an instance share the same set of data. Another way to put it:  By instantiating a class, you are currying multiple functions with a single call.

Which "pattern"  to use depends on what you need. If  you need a general, reusable, extensible solution, OO-style is the way.  If you just want a function that can multiply its argument by 2, currying is simpler. Especially if your language supports it. So I'm not saying "currying is bad". I'm saying it is not missed much in the Object-Oriented way of programming.

There are two additional benefits instantiation has over "currying" (or "partial application").  In a typical implementation of currying you can't curry an argument without currying the arguments before it as well. Can you?  Whereas with instantiation you can decide which subset of data-members of the instance you "fix" with non-default values.  Secondly if your language supports currying out of the box it can't support default arguments: If you don't provide a value for an argument, it doesn't mean a default value will be used for it. It means currying ensues.    


© 2014 Panu Viljamaa. All rights reserved  

UPDATE:  Thanks for several posters at Google+ who pointed out the subtle difference between "Currying" and "Partial Application".  I modified the text above to make it clear my use of the term 'currying' is technically incorrect.