Stateful Function Composition Chain

by plus5keen

JavaScript

(function (global) {
    'use strict';

    global.asComposable = function (fn) {
        var fns = [fn];
        var result = function (value) {
            for (var i = 0, il = fns.length; i < il; i++) {
                var fn = fns[i];
                value = fn(value);
            }
            return value;
        };
        result.compose = function (newFn) {
            fns.push(newFn);
            return result;
        };
        return result;
    };
}(this));

(function (global) {
    var log = (function () {
        var c = global.console;
        var l = c.log;
        return function () { l.apply(c, arguments); };
    }());
    
    function logId(x) { log(x); return x; }
    
    function add(a) { return function (b) { return a + b; }; }
    
    function multiply(a) { return function (b) { return a * b; }; }
    
    var f = asComposable(logId);
    
    f // f.compose() changes f itself, so no assignment is necessary
    .compose(add(4)).compose(logId)
    .compose(add(1)).compose(logId)
    .compose(multiply(2)).compose(logId)
    .compose(add(-6)).compose(logId)
    .compose(multiply(0.5)).compose(logId);
    
    log('f(-1)');
    f(-1);
    log('f(0)');
    f(0);
    log('f(1)');
    f(1);
}(this));