Search code examples
javascriptnode.jsv8

Function Composition of JavaScript and Haskell


In JavaScript we can define function composition as using a function which takes two functions f and g, to produce a new function:

function o(f, g) {
  return function(x) {
   return f(g(x));
  }
 }

This seems obvious, but my question is, does the runtime interpreter/compiler actually calculate f(g(x))?

Say we have some large data like an array with many elements, and is the previously composed function o as the f(g(x)) by the prior calculation faster than uncomposed f(g(x)) ?

Perhaps, in this case, o(f, g) as merely a macro expression of f(g(x))?

And if it's a macro, perhaps, the performance doesn't make much difference?

It may depends on the runtime environment, I especially interested in V8 engine for Chrome/node.js.

Haskell as a language of lazy evaluation strategy theoretically compose functions, am I correct? Does GHC actually calculate to compose functions?


Solution

  • No, the function call o(f, g) will return exactly the anonymous function:

    function (x) {
        return f(g(x));
    }
    

    Then, only at the time, when you call that anonymous function, g(x) will execute and then f will execute on the result of g(x). Every time you call that anonymous function both g and f execute, one after the other. So the using the composed function will be just a little slower than manually calling f(g(x)) everywhere in your code due to the slight overhead of the extra anonymous function.

    Example:

    function o(f, g){
        return function(x) {
            return f(g(x));
        }
    }
    
    function addTo5(x){
        return x + 5;
    }
    
    function multiplyBy(x){
        return function(y){
            return x*y;
        }
    }
    
    var composed = o(multiplyBy, addTo5);
    composed(5)(3); // Slightly slower than multiplyBy(addTo5(5))(3)
    

    jsperf