gypsydave5

The blog of David Wickes, software developer

(not quite) Currying in JavaScript

Currying, yet another I’ve heard the cool kids saying that word. Acually, having done some reading, it turns out the cool kids may be misusing it, but we’ll get to that part later. Let’s just spend a minute looking at the wonder of .bind().

Here’s a function:

function addition(a, b) {
    return a + b
}

addition(1, 2) //=> 3

Let’s say we always wanted to be adding twenty-two - we could make ourselves a shiny new function, or we could build on the way addition works using .bind()

var addTwentyTwo = addition.bind(this, 22)
addTwentyTwo(1) //=> 23

bind(), as you’ll see in the MDN docs, is a method you can call on a function in JavaScript. It creates a new function based on the old one, with the this keyword of the new function set to the first argument to bind(), and other arguments given being set to the arguments of the original function. Confusing, right? Well, it’s probably best to ignore the first arpument, the this reassignment for now, unless there’s a pressing need to change it, and focus on the rest. Here, let’s do it again:

var twentyFive = addTwentyTwo.bind(this, 3)
twentyFive() //=> 25

When we use .bind() we can change the arity (number of ardguments) of the function returned, setting the values of any of all of the arguments in the original function:

var twoHundred = addition.bind(this, 50, 150)
twoHundred() //=> 200

What bind allows us to do is partial application, fixing values of a function and returning one of smaller arity:

function addTheseFourUp(a, b, c, d) {
    return a + b + c + d
}

var addTwoAndTheseThreeUp = addTheseFourUp(this, 2)

addTwoAndTheseThreeUp(1, 2, 3) //=> 8

This is technically not currying, which should only return functions with an arity of 1. Currying addTheseFourUp would look something like this:

function curriedFour(a) {
    return function(b) {
        return function(c) {
            return function (d) {
                return a + b + c + d
            }
        }
    }
}

curriedFour(1)(2)(3)(4) //=> 10

Which we could also play around with like this…

function applyFourTimes(fun) {
    return function(num) {
        return fun(fun(fun(fun(num))))
    }
}

function double(num) {
    return num + num
}

applyFourTimes(double)(3) //=> 48

Postscript

Not only is partial function application not currying - but currying should probably be called Schönfinkelization after its true originator, Moses Schönfinkel, to whom Haskell Curry attributed the concept. That said, W. V. O. Quine points out that the idea had already been hit upon by Frege.

From JavaScript to philosophy in but a few skips…