munificent / journal

My blog, in all its statically-generated glory.

Home Page:http://journal.stuffwithstuff.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

re: what-color-is-your-function

404pnf opened this issue · comments

commented

original function

  function makeSundaeOriginal(callback) {
    scoopIceCream(function (iceCream) {
      warmUpCaramel(function (caramel) {
        callback(pourOnIceCream(iceCream, caramel));
      });
    });
  }

with a biased assumption

scoopIceCream and warmUpCaramel are used only for side-effect?

pourOnIceCream is used though.

let me assume the intention is this

      function makeSundae(callback) {
        return function (iceCream) {
          return function (caramel) {
            return callback(pourOnIceCream(iceCream, caramel));
          };
        };
      }

      // try to simplify that


      var _ = require('ramda'),
        add = _.curry(function (a, b) { return a + b }),
        pourOnIceCream = add
        log = console.log;


      //step 1

      var makeSundaeSimpl  = function (callback) {
        return _.compose(callback, pourOnIceCream)
      };

      // step 2

      var makeSundaeSimpl = function (callback, pourOnIceCream) {
        _.compose(callback, pourOnIceCream)
      };

      // step 3

      var makeSundaeSimpl = _.compose;

      makeSundaeSimpl(log, add)(1, 2)

YES! makeSundae is the good old compose.
Or composeP if callback and pourOnIceCream are promises.
http://ramdajs.com/0.15/docs/#composeP
We don't need to defined it ourselves.
But we need to pass in the argument iceCream and caramel together.

      // get fancy?

      var g = _.curry(function (cb, f, a, b) {
        cb(f(a,b))
      });

      g(log, add)(1, 2)
      g(log, add)(1)(2)
      g(log)(add)(1, 2)
      g(log)(add)(1)(2)
      // =>  all log 3 to screen

without assumptions

callbcak, warmUpCaramel and scoopIceCream will be called in the order of the orignal function. They can be promise functions or regular functions. pipeP can handle both. Use async.seq if you like.

    var R = require('ramda'),
        v1,
        add,
        warmUpCaramel,
        scoopIceCream,
        log = console.log;

    v1 = R.curry(function (callback, iceCream, caramel) {
        var f = function () {
            return callback(iceCream, caramel);
        };
        R.pipeP(f, warmUpCaramel, scoopIceCream)();
    });

    add = function (a, b) {
        log('add', a + b);
        return a + b;
    };

    warmUpCaramel = function (x) {
        log('warmUpCaramel', x);
        return x;
    };

    scoopIceCream = function (x) {
        log('warmUpCaramel', x);
        return x;
    };

    v1(add, 1,2)
    v1(add)(1,2)
    v1(add)(1)(2)

    // all log to console
    // add 3
    // warmUpCaramel 3
    // warmUpCaramel 3

but the code is longer!

That's because in the original funciton, all helper functions are defined somewhere else. Taking that approch, the function most likely mimic the orignal one would be:

    var R = require('ramda'),
        v1;
    v1 = R.curry(function (callback, iceCream, caramel) {
            var f = function () {
                return callback(iceCream, caramel);
            };
            R.pipeP(f, warmUpCaramel, scoopIceCream)();
        });

scoopIceCream and warmUpCaramel are used only for side-effect?

No, they do some work (synchronously and/or asynchronously) to produce iceCream and caramel. They "return" those values by invoking the callbacks they are given with those as arguments. :)