Posts Tagged ‘aspect orientation’

Extending, Currying and Monkey Patching. part 3

May 27, 2012

Monkey Patching

Or sometimes known as Duck Punching.

So what we’ve got here is an arbitrary object kimsObject (line 01) thrown in the BINARYMIST global, with a public method kimsMethod (line 03).
The trace method is passed an object and a method name (line 10). It replaces the specified
method with a new method that “wraps” additional functionality around the original method.
The call is made from line 23

var BINARYMIST = {};
BINARYMIST.kimsObject = (function () {
  return {
    kimsMethod: function () {
      alert("Now inside kimsMethod.");
    }
  };
}());

BINARYMIST.trace = (function () {
  return function (targetObject, targetMethod) {
    var originalMethod = targetObject[targetMethod];
    var that = this;
    (function () {
      console.log(new Date(), "Entering:", targetMethod);
      var result = originalMethod.apply(that, arguments);
      console.log(new Date(), "Exiting:", targetMethod);
      return result;
    }(/*execute me!*/));
  };
}());

(function () {
  BINARYMIST.trace(BINARYMIST.kimsObject, 'kimsMethod')
}());

I believe if used with care, and in moderation.
Monkey Patching can support and provide implementation for
Dr. Barbara Liskov’s Liskov Substitution Principle (LSP)

Consider the developer that uses a function he/she thinks does something, but it actually does something entirely unexpected.
Be sure to make known to the team and those what will use your code what you have done, and what they can expect.
Make sure this is documented in code around the API, whether it be with comments or simply in the way you write your code.

monkey patching

Jeff Atwood has a good post on the dangers of using Monkey Patching.
Be sure to check it out.

You may or may not need the Object.create function. It’s part of the ECMA Standard 262
which is the vendor-neutral standard for what was originally Netscape’s JavaScript.
This allows us to specify the object we want to be the prototype for our new object, I.E. our base class.
Properties added to an object‘s prototype are shared, through inheritance, by all objects sharing the prototype.
Alternatively, a new object may be created with an explicitly specified
prototype by using the Object.create built-in function.

This also makes me think of what we try to achieve with Aspect Orientation in .NET.
Below I’ve had an attempt at trying to make the BINARYMIST.createAspectedObjectWithTracing as generic as possible.
So that on the last line you can instantiate a BINARYMIST.kimsObject and call the kimsMethod method.
The way I’ve setup the BINARYMIST.createAspectedObjectWithTracing, you should be able to instantiate any object and call which ever method on it that you desire.
You get the tracing functionality for free.
Using this sort of approach, you should be able to apply any functionality you want to any method you want.

I’m keen on hearing how this could be improved.
Making the call even more transparent.

BINARYMIST.kimsObject = (function () {
  return {
    kimsMethod: function () {
      alert("Now inside kimsMethod.");
    }
  };
}());

BINARYMIST.trace = (function () {
  return function (targetObject, targetMethod) {
    var originalMethod = targetObject[targetMethod];
    var that = this;
    (function () {
      console.log(new Date(), "Entering:", targetMethod);
      // We can pass any number of args to the original method we wanted to call.
      // We also handle any return value. So hopefully this should be able to be used for any method.
      var result = originalMethod.apply(that, arguments);
      console.log(new Date(), "Exiting:", targetMethod);
      return result;
    }(/*execute me!*/));
  };
}());

// Add create method to the Object function
// Gives us dynamic control of what a base class should look like.
// method (create) that takes an object argument, returns a new object that has the parameter assigned to it's prototype.
// Creates a function on Object (create) that takes an object argument.
// Creates a function (Func) and assigns the object parameter to the function definition's prototype.
// Instantiates and assigns the new function (Func) to the "create" function definition on Object.
(function () {
  if (typeof Object.create !== 'function') {
    Object.create = function (o) {
      var Func = function () {};
      Func.prototype = o;
      return new Func();
    };
  }
}());

BINARYMIST.createAspectedObjectWithTracing = (function (anyObject, anyFunction) {
  var localObject = Object.create(anyObject);
  localObject[anyFunction] = function () {
    return BINARYMIST.trace(anyObject, anyFunction);
  };
  return localObject;
});

// Instantiate your object (any object) and call a method on it.
BINARYMIST.createAspectedObjectWithTracing(BINARYMIST.kimsObject, 'kimsMethod').kimsMethod();

Now as you can see again, all of the objects I’ve defined are sitting tidily out of the global object.

javascript global abatement

Now as you can see below, our BINARYMIST.kimsObject is now part of the new object’s (that localObject references) prototype object.
and it’s method is clearly visible.

javascript prototype

On line 42 above, we set the localObject‘s kimsMethod  to reference a wrapped version of BINARYMIST.kimsObject.kimsMethod.
The wrapped version has the tracing added.

We then return the localObject which references BINARYMIST.kimsObject and call the most specific kimsMethod
which has the functionality we just set.

return BINARYMIST.trace(anyObject, anyFunction);

and as you can see below, we’re now ready to start playing with our target method (kimsMethod).

javascript tracing

We then assign the this. We then execute the  anonymous closure.
In doing so, this is bound to the global object.
So to access the outer scope we need the that.
We then apply the originalMethod to that (BINARYMIST in our case).

Extending, Currying and Monkey Patching. part 2

May 14, 2012

Currying

Currying got it’s name from Haskell Curry,

Haskell Curry

originally discovered by Moses Schönfinkel.

schonfinkel

The programming language Haskell named after Haskell Curry is a purely functional language.
So the concept of Currying has it’s roots in functional programming.

It seems that the concepts of Currying and Partial Function Application are often used interchangeably, although they are different.
Lets try and shed some light on the confusion.

Function Application

In carrying on from part 1 of this topic “Extending, Currying and Monkey Patching”
When it comes to functional programming languages, strictly speaking we don’t so much use the terms calling or invoking a function.
We apply functions.
As you can see in the next example, calling or applying a function has the same effect.
Lines 36, 40 and 45 all do the same thing.

// In JavaScript
var coffeeAttributes;
var BINARYMIST;

BINARYMIST = (function (binMist) {
   return binMist;
} (BINARYMIST || {}));

BINARYMIST = (function (binMist) {

  var capitaliseFirstChar = function (target) {
    return target.replace(/^\w/, function (character) { return character.toUpperCase(); });
  };

   binMist.coffeeAttributes = function (myPoison) {
      try {
        // If String.prototype.toLowerCase fails, myPoison isn't a string
        var poison = (myPoison || "").toLowerCase();
      } catch (e) {
        return "Looks like the argument you passed wasn't a string.";
      }

      if(poison === "real coffee")
        return capitaliseFirstChar(poison) + " provides great taste and a good buzz.";
      if(poison === "instant coffee")
        return capitaliseFirstChar(poison) + " provides terrible taste and minimal buzz.";
      if(poison)
        return "I don't recognise " + poison + ". It's attrbutes could be anyones guess.";

      return "well it depends on what type of coffee we're talking about.";
  };
  return binMist;
}(BINARYMIST || {}));

// Call or invoke your function.
coffeeAttributes = BINARYMIST.coffeeAttributes( new String("Real coffee"));
document.writeln(coffeeAttributes + '<br>');
// Real coffee provides great taste and a good buzz.

coffeeAttributes = BINARYMIST.coffeeAttributes('instant Coffee');
document.writeln(coffeeAttributes + '<br>');
// Instant coffee provides terrible taste and minimal buzz.

// Apply your function.
coffeeAttributes = BINARYMIST.coffeeAttributes.apply(null, ["pseudo coffee"]);
document.writeln(coffeeAttributes + '<br>');
// I don't recognise pseudo coffee. It's attrbutes could be anyones guess.

In essence, how we code  a function call / invocation is syntactic sugar for the slightly longer form “function application”.

Partial Application

Or partial function application…

  • returns a function which behaves like the function you pass in but which takes fewer arguments, because the others have been bound into the returned function.
  • takes a function and from it builds a function which takes fewer arguments.

Implementing Partial Application

Now we could continue with the same theme as above, but for the purpose of providing easy understanding, I’m going to use a simpler theme.
I’ve seen the add function used a few times to explain the topic, so I’m going to use it as well.
We’re going to look at the examples in both JavaScript and C#.
Don’t get to caught up on the C# examples, as I’ve never had a need to curry in C#.
They’re just there to provide some contrast.

// In JavaScript
var BINARYMIST;
var fullApplicationResult;
var add9;
var partialApplicationResult;

BINARYMIST = (function (binMist) {
   return binMist;
} (BINARYMIST || {}));

BINARYMIST = (function (binMist) {
  binMist.add = function (firstParam, secondParam) {
    var firstLocal = (typeof firstParam === 'number') ? firstParam : 0;
    var secondLocal = (typeof secondParam === 'number') ? secondParam : 0;
    return firstLocal + secondLocal;
  }
  return binMist;
}(BINARYMIST || {}));

BINARYMIST.partialApply = (function () {
  return function (localFunction, param2) {
    return function (param3) {
      return localFunction(param2, param3);
    }
  }
}());

fullApplicationResult = BINARYMIST.add.apply(null, [9, 6]);
document.writeln('Full Function Application results: ' + fullApplicationResult + '<br>');
// Full Function Application results: 15

add9 = BINARYMIST.partialApply.apply(null, [BINARYMIST.add, 9]);
partialApplicationResult = add9(6);
document.writeln('Partial Function Application results: ' + partialApplicationResult + '<br>');
// Partial Function Application results: 15
// In C#
using System;

namespace BinaryMist {
    class Program {

        static string Add(int firstParam, int secondParam) {
            return (firstParam + secondParam).ToString();
        }

        static Func<T2, TResult> PartialApply<T1, T2, TResult>(Func<T1, T2, TResult> localFunction, T1 param2) {
            return (param3) => localFunction(param2, param3);
        }

        static void Main(string[] args) {
            Func<int, int, string> kimsAdd = Add;

            Func<int, string> add9 = PartialApply(kimsAdd, 9);
            string partialApplicationResult = add9(6);
            Console.WriteLine("Partial Function Application results: {0}", partialApplicationResult);
            // Partial Function Application results: 15
        }
    }
}

Now with an add method that takes 3 arguments:

// In JavaScript
var BINARYMIST;
var add9;
var partialApplicationResult;

BINARYMIST = (function (binMist) {
   return binMist;
} (BINARYMIST || {}));

BINARYMIST = (function (binMist) {
  binMist.add = function (firstParam, secondParam, thirdParam) {
    var firstLocal = (typeof firstParam === 'number') ? firstParam : 0;
    var secondLocal = (typeof secondParam === 'number') ? secondParam : 0;
    var thirdLocal = (typeof thirdParam === 'number') ? thirdParam : 0;
    return firstLocal + secondLocal + thirdLocal;
  }
  return binMist;
}(BINARYMIST || {}));

BINARYMIST.partialApply = (function () {
  return function (localFunction, param2) {
    return function (param3, param4) {
      return localFunction(param2, param3, param4);
    }
  }
}());

add9 = BINARYMIST.partialApply.apply(null, [BINARYMIST.add, 9]);
partialApplicationResult = add9(6, 2);
document.writeln('Partial Function Application results: ' + partialApplicationResult + '<br>');
// Partial Function Application results: 17
// In C#
using System;

namespace BinaryMist {
    class Program {

        static string Add(int firstParam, int secondParam, int thirdParam) {
            return (firstParam + secondParam + thirdParam).ToString();
        }

        static Func<T2, T3, TResult> PartialApply<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> localFunction, T1 param2) {
            return (param3, param4) => localFunction(param2, param3, param4);
        }

        static void Main(string[] args) {
            Func<int, int, int, string> kimsAdd = Add;

            Func<int, int, string> add9 = PartialApply(kimsAdd, 9);
            string partialApplicationResult = add9(6, 2);
            Console.WriteLine("Partial Function Application results: {0}", partialApplicationResult);
            // Partial Function Application results: 17
        }
    }
}

and again, but broken out into stages:

// In JavaScript
var BINARYMIST;
var add9;
var add6;
var add2;
var partialApplicationResult;

BINARYMIST = (function (binMist) {
   return binMist;
} (BINARYMIST || {}));

BINARYMIST = (function (binMist) {
  binMist.add = function (firstParam, secondParam, thirdParam) {
    var firstLocal = (typeof firstParam === 'number') ? firstParam : 0;
    var secondLocal = (typeof secondParam === 'number') ? secondParam : 0;
    var thirdLocal = (typeof thirdParam === 'number') ? thirdParam : 0;
    // Time to un-wind the call stack
    return firstLocal + secondLocal + thirdLocal;
  }
  return binMist;
}(BINARYMIST || {}));

BINARYMIST.partialApply = (function () {
  // Because of JavaScript's dynamic typing, we don't need to overload our methods.
  return function (localFunction, param2) {
    return function (param3, param4) {
      return localFunction(param2, param3, param4);
    }
  }
}());

add9 = BINARYMIST.partialApply.apply(null, [BINARYMIST.add, 9]);
add6 = BINARYMIST.partialApply.apply(null, [add9, 6]);
add2 = BINARYMIST.partialApply.apply(null, [add6, 2]);
// Time to wind the call stack up.
partialApplicationResult = add2();
document.writeln('Partial Function Application results: ' + partialApplicationResult + '<br>');

 

// In C#
using System;

namespace BinaryMist {
    class Program {

        static string Add(int firstParam, int secondParam, int thirdParam) {
            // Time to un-wind the call stack.
            return (firstParam + secondParam + thirdParam).ToString();
        }

        // Because of C#'s static typing, we need 3 overloaded methods.
        static Func<T2, T3, TResult> PartialApply<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> localFunction, T1 param2) {
            return (param3, param4) => localFunction(param2, param3, param4);
        }

        // Because of C#'s static typing, we need 3 overloaded methods.
        static Func<T2, TResult> PartialApply<T1, T2, TResult>(Func<T1, T2, TResult> localFunction, T1 param2) {
            return param3 => localFunction(param2, param3);
        }

        // Because of C#'s static typing, we need 3 overloaded methods.
        static Func<TResult> PartialApply<T1, TResult>(Func<T1, TResult> localFunction, T1 param2) {
            return () => localFunction(param2);
        }

        static void Main(string[] args) {
            Func<int, int, int, string> kimsAdd = Add;

            Func<int, int, string> add9 = PartialApply(kimsAdd, 9);
            Func<int, string> add6 = PartialApply(add9, 6);
            Func<string> add2 = PartialApply(add6, 2);
            // Time to wind the call stack up.
            string partialApplicationResult = add2();
            Console.WriteLine("Partial Function Application results: {0}", partialApplicationResult);
            // Partial Function Application results: 17
        }
    }
}

Currying

  • is creating a function that understands partial application and implements it.
  • builds functions which take multiple arguments by composition of functions which each take a single argument.

Implementing Currying

Now the function that takes the single argument is on line 48.
The composition of functions is performed in the same function where we return that (which is the original add applied to the parameter of 9 for the first test).
So in this function we actually return add applied to 9 concatenated to 6.
The original 9 is held in argumentsArray.
I’ve also modified the add method to be a little more flexible and deal with n number of arguments.

// In JavaScript
// Setup our global
var BINARYMIST;

// Variables for testing
var add9;
var sixteen;
var addOne;
var fortyOne;
var addSix;

// First up we add a method to Function's prototype.
// In JavaScript every object (incl Function) is linked to a prototype object
// This allows us to add any function to Function's prototype
Function.prototype.method = (function (name, func) {
  // Add the function (func) as a property of Function's prototype object.
  this.prototype[name] = func;
  return this;
});

// This is our add method repeated from above.
BINARYMIST = (function (binMist) {
  binMist.add = function () {
    var addend;
    var sum = 0;
    for (arg in arguments) {
      if (arguments.hasOwnProperty(arg)) {
        addend = arguments[arg];
        sum += (typeof addend === 'number') ? addend : 0
      }
    }
    return sum;
  }
  return binMist;
}(BINARYMIST || {}));

// Second we add a function called curry to the global Functions prototype.
Function.method('curry', function ( ) {
  // Because we want to concatenate 2 lots of the arguments, we need arguments to be of type Array.
  // Because the arguments parameter is not a real array, we need to borrow the slice method from Array.prototype.
  var slice = Array.prototype.slice;
  // Create an array from arguments.
  var argumentsArray = slice.apply(arguments);
  // In our case, this is bound to add because it's add's prototype's curry method that we invoked.
  var that = this;
  return function ( ) {
    // We now apply add (which is referenced by that) to the current scope, which is the curried function (add9, in this case).
    return that.apply(null, argumentsArray.concat(slice.apply(arguments)/*Create a real array from arguments.*/)/*Concatenate it with the curry parameter*/);
  };
});

Testing curry

// In JavaScript

// Execute the curry method which is a member of add's prototype.
add9 = BINARYMIST.add.curry(9);
document.writeln("Curry results: " + add9(6) + '<br>'); // Curry results: 15

// Single-step currying. Works with any number of arguments.
addSixteen = BINARYMIST.add.curry(1, 2, 3)(5, 5);
document.writeln("Curry results: " + addSixteen + '<br>'); // Curry  results: 16

// Two-step currying.
addOne = BINARYMIST.add.curry(1);
addSix = BINARYMIST.add.curry(3, 1, 2);
fortyOne = addOne(10, 10, 10, 10);
six = addOne(2, 3);
sixteen = addSix(5, 5);

As you can see from the C# example below, dynamic languages such as JavaScript, make currying less verbose and provide considerably more flexibility.

Currying in C# feels a little awkward.

// In C#
using System;

namespace BinaryMist {
    class Program {

        static int Add(int firstParam, int secondParam, int thirdParam) {
            // Time to un-wind the call stack.
            return firstParam + secondParam + thirdParam;
        }

        static Func<T1, Func<T2, Func<T3, TResult>>> Curry<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> function) {
            return a => b => c => function(a, b, c);
        }

        // Testing curry
        static void Main(string[] args) {
            Func<int, int, int, int> kimsAdd = Add;

            string curryResult = "Curry results: {0}";

            // Single-step currying.
            var curried = Curry(kimsAdd);
            Console.WriteLine(curryResult, curried(9)(6)(3));
            // Curry results: 18

            // Two-step currying.
            Func<int, Func<int, Func<int, int>>> curryAdd = Curry(kimsAdd);
            Func<int, Func<int, int>> add9 = curryAdd(9);
            Func<int, int> add15 = add9(6);
            Console.WriteLine(curryResult, add15(3));
            // Curry results: 18
        }
    }
}

Why / where would we want to Curry

If you are making calls to a particular function with some of the same arguments every time.
You could dynamically create a function that holds on to the previously repeated parameters, thus saving you the effort of passing them every time.
This function will supply the original function with it’s saved parameters, so the original function has the full set.
Currying is not really needed in C#. The examples provided are for academic purposes only.

To wrap up:

Although I don’t think there is much use for explicit Partial Application or Currying in C#,
Jon Skeet has an interesting blog post on Partial Application and Currying in C#, with:

  1. some sample code useful for stepping through
  2. a good controversial and thought provoking conversation following

This post also provided some clarification.

Other Insights obtained from the excellent:

  1. Doug Crockfords JavaScript The Good Parts
  2. Stoyan Stefanov’s JavaScript Patterns