Sunday 29 September 2019

Functional Programming

I have to admit that I've never been into Functional Programming. I mean, I've used and loved for quite long some techniques related to Functional Programming, like: map, filter, forEach, closures, partial functions... but I've always used this as part of my OOP programming, I've never got into some other functional techniques and all the functional hype.

Last year I wrote this crappy post where as you can see I still could hardly see any particular use to function currying. Well, that has changed in the last days thanks to this article about currying and this article about lodash-fp.

The main element about currying that I had been missing is that a curried function can be invoked not just passing one argument at each call, but several arguments in one call (this is called Variadic Currying). I mean:

function myFunc(a, b, c){....}

//given a curried version of myFunc we can do:
myCurriedFunc(a)(b)(c);

//but also:
myCurriedFunc(a, b)(c);
myCurriedFunc(a)(b, c);
myCurriedFunc(a, b, c);

Not taking into account Variadic Currying, one could see no particular difference between Partial Function Application and Currying.

var _ = require('lodash');

function wrapTwice(wrapper, txt){
    return `${wrapper.repeat(2)} ${txt} ${wrapper.repeat(2)}`;
}

const wrapWithXPartial = _.partial(wrapTwice, "X");
const wrapWithXCurry = _.curry(wrapTwice)("X");

console.log(wrapWithXPartial("hi"));
//XX hi XX

console.log(wrapWithXCurry("hi"));
//XX hi XX

But Variadic Currying allows us to write this:

const curriedWrapTwice = _.curry(wrapTwice);
console.log(curriedWrapTwice("X", "hi"));
console.log(curriedWrapTwice("X")("hi"));

In the first invocation we are invoking the curried function just in the same was as we would invoke the original function. So we could just curry all our functions beforehand and then invoke them normally (with all the parameters) or in the curried style (one or x parameters at each time). Now you can wonder, "OK, and what for?". To answer this, you just have to read the second aforementioned article, and play around with lodash/fp. You'll also learn a piece of jargon "point-free programming" to throw around from time to time during an office coffee break.

By the way, the introductory paragraph:
The lodash/fp module promotes a more functional programming (FP) friendly style by exporting an instance of lodash with its methods wrapped to produce immutable auto-curried iteratee-first data-last methods.
could let you speechless (I've sent it to one friend to have fun with his reaction :-)... so a basic explanation:

  • auto-curried: What I mentioned above, the lodash/fp functions (map, filter...) have already been curried.
  • iteratee-first data-last: The parameters order with respect to their lodash counterparts has been inverted. We have lodash.map(collection, callback), and lodash/fp.map(callback, collection)

No comments:

Post a Comment