Functional

Programming

in

5 Minutes

Which is impossible

So let's rather try...

Learn to Curry

in

5 Minutes

JSDC.tw 2013 Lightning Talk

Gias Kay Lee

gsklee.im

Currying.

Perhaps you've been told by someone before that this is one of those "advanced JavaScript techniques" you'll need to learn to become a true JavaScript ninja.

But the truth is...

http://commons.wikimedia.org/wiki/File:Phanaeng_kai.jpg

Currying,


is a basic functional programming technique.

And in order to become a true JavaScript ninja,
what you really need to master is the art of


Functional Programming.

Lisp

Scheme

Functional

Smalltalk

Self

Object-oriented

has half of its root in it.

Because JavaScript

Let's start with something

familiar

λ Function

AKA Anonymous Function

originated from a mathematical system called

λ Calculus

λ Calculus

is about simplifying mathematical expressions into


λ Expressions

to unveil the true nature of underlying computations

To achieve this simplification

Functions


cube(x) = x * x * x


are expressed without names


(x) → x * x * x

...and can only have


1 argument

To handle a


multi-argument function




it needs to first go through the process of...

Currying (n.)


A technique of transforming a multi-argument function in such a way that it can be called as a chain of functions, each with a single argument.

And the name comes from...

http://commons.wikimedia.org/wiki/File:Curry_Ist.jpg

Haskell Curry

(1900 – 1982)

also immortalized as the name of

the popular pure functional language

Haskell

http://en.wikipedia.org/wiki/File:Haskell-Logo.svg

So

(x, y) → x + y



can be curried into

x → (y → x + y)

Or, in classical notation

f(x, y) = x + y



can be curried into

g(x) = y → f(x, y)

Still very confusing?




Let's speak JavaScript!

a multi-argument function

function(x, y) {

    return x + y;

}

when curried, will become

a chain of functions, each

with a single argument

function(x) {

    return function(y) {

        return x + y;

    };

}

if we give them names

function f(x, y) {

    return x + y;

}


then...


function g(x) {

    return function(y) {

        return x + y;

    };

}


f(1, 2) === g(1)(2);

now, since functions are

first-class citizens...


we can also do it

like this


function g(h) {

    return function(y) {

        return h(h(y));

    };

}


81 === g(function(x) {

    return x * x;

})(3);

function g(h) {

    return function(y) {

        return h(h(y));

    };

}


if we only supply

one of the arguments

to the curried function...


var n = g(function(x) {

    return x * x;

});


we'll be able to reuse it

like this


337 === n(3) + n(4);

This is called


Partial Application


and is not the same with currying

actually, for functions with

an arity greater than 2

function f(x, y, z) {

    return x + y + z;

}


the correct way to

partially apply is through

bind()


var f1 = f.bind(null, 1);


call to a partially applied

function returns the result,

not another function down

the currying chain


6 === f1(2, 3);

Now I guess we're


running low on time


so...

One last bit


that the reverse process of currying

uncurrying

is closely related with

a more familiar concept

apply.

Questions?

Nah, we're running outta time. Seriously.



This slide can be found on

slid.es/gsklee