187

I don’t think I’ve grokked currying yet. I understand what it does, and how to do it. I just can’t think of a situation I would use it.

Where are you using currying in JavaScript (or where are the main libraries using it)? DOM manipulation or general application development examples welcome.

One of the answers mentions animation. Functions like slideUp, fadeIn take an element as an arguments and are normally a curried function returning the high order function with the default “animation function” built-in. Why is that better than just applying the higher-up function with some defaults?

Are there any drawbacks to using it?

As requested here are some good resources on JavaScript currying:

I’ll add more as they crop up in the comments.


So, according to the answers, currying and partial application in general are convenience techniques.

If you are frequently “refining” a high-level function by calling it with same configuration, you can curry (or use Resig’s partial) the higher-level function to create simple, concise helper methods.

Dave Anderson
  • 11,836
  • 3
  • 58
  • 79
Dave Nolan
  • 3,009
  • 4
  • 30
  • 32
  • can you add a link to a resource that describes what JS currying is? a tutorial or a blog post would be great. – Eric Schoonover Sep 22 '08 at 08:31
  • 2
    svendtofte.com is longwinded but if you skip the whole section from "A crash course in ML" and start again at "How to write curried JavaScript" it becomes a great introduction to currying in js. – danio Sep 24 '08 at 13:38
  • 1
    This is a good starting point to understand what curry and partial application really is: http://slid.es/gsklee/functional-programming-in-5-minutes – gsklee May 27 '13 at 03:24
  • 1
    The link to `svendtofte.com` looks to be dead - found it on the WayBack machine though at https://web.archive.org/web/20130616230053/http://www.svendtofte.com/code/curried_javascript/ Sorry, http://blog.morrisjohns.com/javascript_closures_for_dummies seems to be down too – phatskat Jan 30 '14 at 14:59
  • 1
    BTW, Resig's version of partial is deficient (certainly not "on the money") in that it will likely fail if one of the pre–initialised ("curried") arguments is given the value *undefined*. Anyone interested in a good currying function should get the original from [Oliver Steele's *funcitonal.js*](http://osteele.com/sources/javascript/functional/), as it doesn't have that problem. – RobG Apr 12 '14 at 22:59

17 Answers17

114

Here's an interesting AND practical use of currying in JavaScript that uses closures:

function converter(toUnit, factor, offset, input) {
    offset = offset || 0;
    return [((offset + input) * factor).toFixed(2), toUnit].join(" ");
}

var milesToKm = converter.curry('km', 1.60936, undefined);
var poundsToKg = converter.curry('kg', 0.45460, undefined);
var farenheitToCelsius = converter.curry('degrees C', 0.5556, -32);

milesToKm(10);            // returns "16.09 km"
poundsToKg(2.5);          // returns "1.14 kg"
farenheitToCelsius(98);   // returns "36.67 degrees C"

This relies on a curry extension of Function, although as you can see it only uses apply (nothing too fancy):

Function.prototype.curry = function() {
    if (arguments.length < 1) {
        return this; //nothing to curry with - return function
    }
    var __method = this;
    var args = toArray(arguments);
    return function() {
        return __method.apply(this, args.concat([].slice.apply(null, arguments)));
    }
}
Alejandro Vales
  • 2,816
  • 22
  • 41
Prisoner ZERO
  • 13,848
  • 21
  • 92
  • 137
  • 5
    This is great! I see it similar to the lisp quote that says "Lisp is a programmable programming language" – santiagobasulto Sep 06 '11 at 19:48
  • Okay...maybe I'm dumb...but I have no idea what you mean? – Prisoner ZERO Sep 28 '11 at 17:34
  • 2
    Interesting, but this example doesn't appear to work. `offset+input` will be `undefined + 1.60936` in your `milesToKm` example; that results in `NaN`. – Nathan Long Oct 12 '11 at 19:35
  • 3
    @Nathan - offset can't be undefined - it defaults to 0 – AngusC Nov 10 '11 at 17:44
  • 6
    From what I've read (just now), "curry" is not normally part of a Function's bag of tricks, unless you are using the Prototype library or add it yourself. Very cool, though. – Roboprog Mar 08 '12 at 03:06
  • 11
    The same can be acheived with ES5 bind() method. Bind creates a new function that when called calls the original function with the context of its first argument and with the subsequent sequence of arguments (preceding any passed to the new function). So you can do... var milesToKm = converter.bind(this, 'km',1.60936); or var farenheitToCelsius = converter.bind(this, 'degrees C',0.5556, -32); The first argument, the context, this, is irrelevant here so you could just pass undefined. Of course you would need to augment the base Function prototype with your own bind method for non ES5 fallback – hacklikecrack Sep 22 '12 at 12:30
  • 2
    Could you include the curry function you are using to make this example more complete? – Shawn Jun 20 '13 at 15:34
  • 1
    I find this very expressive. Thanks! – Olivictor Apr 26 '16 at 00:55
  • When copying a pasting your answer wholesale from another website you must additionally wrap the copied bit in quotes. See http://stackoverflow.com/help/referencing – tom redfern Jul 07 '16 at 10:14
  • var milesToKm = input => converter.curry('km', 1.60936, undefined, input) is a better solution. It is not sensitive to the parameter order. Currying is overrated in JavaScript. – ZunTzu Jul 17 '18 at 09:16
37

@Hank Gay

In response to EmbiggensTheMind's comment:

I can't think of an instance where currying—by itself—is useful in JavaScript; it is a technique for converting function calls with multiple arguments into chains of function calls with a single argument for each call, but JavaScript supports multiple arguments in a single function call.

In JavaScript—and I assume most other actual languages (not lambda calculus)—it is commonly associated with partial application, though. John Resig explains it better, but the gist is that have some logic that will be applied to two or more arguments, and you only know the value(s) for some of those arguments.

You can use partial application/currying to fix those known values and return a function that only accepts the unknowns, to be invoked later when you actually have the values you wish to pass. This provides a nifty way to avoid repeating yourself when you would have been calling the same JavaScript built-ins over and over with all the same values but one. To steal John's example:

String.prototype.csv = String.prototype.split.partial(/,\s*/);
var results = "John, Resig, Boston".csv();
alert( (results[1] == "Resig") + " The text values were split properly" );
Dave Anderson
  • 11,836
  • 3
  • 58
  • 79
Hank Gay
  • 70,339
  • 36
  • 160
  • 222
  • 7
    This is really a bad answer. Currying has nothing to do with partial application. Currying enables function composition. Function composition enables function reuse. Reuse of functions increases code maintainability. It's that easy! –  Jun 24 '16 at 21:31
  • 3
    @ftor sir, you are a very bad answer. Currying is obviously about making functions more tasty. You clearly missed the point. – Callat Jul 19 '18 at 20:03
  • oftentimes it is said that currying is useful for function composition, but I can write a compose function without requiring currying if all my composed functions take one argument. Currying is needed when one or more of the functions take more than one argument. – aestheticsData Aug 03 '21 at 14:12
11

Agreeing with Hank Gay - It's extremely useful in certain true functional programming languages - because it's a necessary part. For example, in Haskell you simply cannot take multiple parameters to a function - you cannot do that in pure functional programming. You take one param at a time and build up your function. In JavaScript it's simply unnecessary, despite contrived examples like "converter". Here's that same converter code, without the need for currying:

var converter = function(ratio, symbol, input) {
    return (input*ratio).toFixed(2) + " " + symbol;
}

var kilosToPoundsRatio = 2.2;
var litersToUKPintsRatio = 1.75;
var litersToUSPintsRatio = 1.98;
var milesToKilometersRatio = 1.62;

converter(kilosToPoundsRatio, "lbs", 4); //8.80 lbs
converter(litersToUKPintsRatio, "imperial pints", 2.4); //4.20 imperial pints
converter(litersToUSPintsRatio, "US pints", 2.4); //4.75 US pints
converter(milesToKilometersRatio, "km", 34); //55.08 km

I badly wish Douglas Crockford, in "JavaScript: The Good Parts", had given some mention of the history and actual use of currying rather than his offhanded remarks. For the longest time after reading that, I was boggled, until I was studying Functional programming and realized that's where it came from.

After some more thinking, I posit there is one valid use case for currying in JavaScript: if you are trying to write using pure functional programming techniques using JavaScript. Seems like a rare use case though.

Byron Katz
  • 492
  • 5
  • 10
  • 4
    Your code is much easier to understand than Prisoner Zero's and it solves the same problem without currying or anything complex. You've got 2 thumbs up and he has almost 100. Go figure. – DR01D Jul 12 '17 at 04:47
7

I found functions that resemble python's functools.partial more useful in JavaScript:

function partial(fn) {
  return partialWithScope.apply(this,
    Array.prototype.concat.apply([fn, this],
      Array.prototype.slice.call(arguments, 1)));
}

function partialWithScope(fn, scope) {
  var args = Array.prototype.slice.call(arguments, 2);
  return function() {
    return fn.apply(scope, Array.prototype.concat.apply(args, arguments));
  };
}

Why would you want to use it? A common situation where you want to use this is when you want to bind this in a function to a value:

var callback = partialWithScope(Object.function, obj);

Now when callback is called, this points to obj. This is useful in event situations or to save some space because it usually makes code shorter.

Currying is similar to partial with the difference that the function the currying returns just accepts one argument (as far as I understand that).

Armin Ronacher
  • 31,998
  • 13
  • 65
  • 69
4

Consider filter function. And you want to write a callback for it.

let x = [1,2,3,4,5,6,7,11,12,14,15];
let results = x.filter(callback);

Assume want to output only even numbers, so:

let callback = x => x % 2 === 0;

Now imagine we want to implement our callback such that depending on scenario it outputs even numbers which are above some threshold number (such number should be configurable).

We can't easily make such threshold number a parameter to callback function, because filter invokes callback and by default passes it array elements and index.

How would you implement this?

This is a good use case for currying:

let x = [1,2,3,4,5,6,7,11,12,14,15];
let callback = (threshold) => (x) => (x % 2==0 && x > threshold);

let results1 = x.filter(callback(5)); // Even numbers higher than 5
let results2 = x.filter(callback(10)); // Even numbers higher than 10

console.log(results1,results2);
Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90
2

It's no magic or anything... just a pleasant shorthand for anonymous functions.

partial(alert, "FOO!") is equivalent to function(){alert("FOO!");}

partial(Math.max, 0) corresponds to function(x){return Math.max(0, x);}

The calls to partial (MochiKit terminology. I think some other libraries give functions a .curry method which does the same thing) look slightly nicer and less noisy than the anonymous functions.

Liam
  • 27,717
  • 28
  • 128
  • 190
Marijn
  • 2,056
  • 2
  • 13
  • 11
2

I know its old thread but I will have to show how this is being used in javascript libraries:

I will use lodash.js library to describe these concepts concretely.

Example:

var fn = function(a,b,c){ 
return a+b+c+(this.greet || ‘'); 
}

Partial Application:

var partialFnA = _.partial(fn, 1,3);

Currying:

var curriedFn = _.curry(fn);

Binding:

var boundFn = _.bind(fn,object,1,3 );//object= {greet: ’!'}

usage:

curriedFn(1)(3)(5); // gives 9 
or 
curriedFn(1,3)(5); // gives 9 
or 
curriedFn(1)(_,3)(2); //gives 9


partialFnA(5); //gives 9

boundFn(5); //gives 9!

difference:

after currying we get a new function with no parameters pre bound.

after partial application we get a function which is bound with some parameters prebound.

in binding we can bind a context which will be used to replace ‘this’, if not bound default of any function will be window scope.

Advise: There is no need to reinvent the wheel. Partial application/binding/currying are very much related. You can see the difference above. Use this meaning anywhere and people will recognise what you are doing without issues in understanding plus you will have to use less code.

Shishir Arora
  • 5,521
  • 4
  • 30
  • 35
1

As for libraries using it, there's always Functional.

When is it useful in JS? Probably the same times it is useful in other modern languages, but the only time I can see myself using it is in conjunction with partial application.

Hank Gay
  • 70,339
  • 36
  • 160
  • 222
1

I would say that, most probably, all the animation library in JS are using currying. Rather than having to pass for each call a set of impacted elements and a function, describing how the element should behave, to a higher order function that will ensure all the timing stuff, its generally easier for the customer to release, as public API some function like "slideUp", "fadeIn" that takes only elements as arguments, and that are just some curried function returning the high order function with the default "animation function" built-in.

gizmo
  • 11,819
  • 6
  • 44
  • 61
  • Why is it better to curry the higherup function rather than simply call it with some defaults? – Dave Nolan Sep 22 '08 at 08:39
  • 1
    Because it's highly more modular to be able to curry a "doMathOperation" with an addition/multiplication/square/modulus/other-calucation at wish than to imagine all the "default" that the higher function could support. – gizmo Sep 22 '08 at 10:52
1

Here's an example.

I'm instrumenting a bunch of fields with JQuery so I can see what users are up to. The code looks like this:

$('#foo').focus(trackActivity);
$('#foo').blur(trackActivity);
$('#bar').focus(trackActivity);
$('#bar').blur(trackActivity);

(For non-JQuery users, I'm saying that any time a couple of fields get or lose focus, I want the trackActivity() function to be called. I could also use an anonymous function, but I'd have to duplicate it 4 times, so I pulled it out and named it.)

Now it turns out that one of those fields needs to be handled differently. I'd like to be able to pass a parameter in on one of those calls to be passed along to our tracking infrastructure. With currying, I can.

William Pietri
  • 3,573
  • 5
  • 26
  • 25
1

JavaScript functions is called lamda in other functional language. It can be used to compose a new api (more powerful or complext function) to based on another developer's simple input. Curry is just one of the techniques. You can use it to create a simplified api to call a complex api. If you are the develper who use the simplified api (for example you use jQuery to do simple manipulation), you don't need to use curry. But if you want to create the simplified api, curry is your friend. You have to write a javascript framework (like jQuery, mootools) or library, then you can appreciate its power. I wrote a enhanced curry function, at http://blog.semanticsworks.com/2011/03/enhanced-curry-method.html . You don't need to the curry method to do currying, it just help to do currying, but you can always do it manually by writing a function A(){} to return another function B(){}. To make it more interesting, use function B() to return another function C().

Fred Yang
  • 2,521
  • 3
  • 21
  • 29
Fred Yang
  • 1
  • 2
0

Just wanted to add some resources for Functional.js:

Lecture/conference explaining some applications http://www.youtube.com/watch?v=HAcN3JyQoyY

Updated Functional.js library: https://github.com/loop-recur/FunctionalJS Some nice helpers (sorry new here, no reputation :p): /loop-recur/PreludeJS

I've been using this library a lot recently to reduce the repetition in an js IRC clients helper library. It's great stuff - really helps clean up and simplify code.

In addition, if performance becomes an issue (but this lib is pretty light), it's easy to just rewrite using a native function.

megawac
  • 10,953
  • 5
  • 40
  • 61
0

You can use native bind for quick, one line solution

function clampAngle(min, max, angle) {
    var result, delta;
    delta = max - min;
    result = (angle - min) % delta;
    if (result < 0) {
        result += delta;
    }
    return min + result;
};

var clamp0To360 = clampAngle.bind(null, 0, 360);

console.log(clamp0To360(405)) // 45
cstuncsik
  • 2,698
  • 2
  • 16
  • 20
0

Another stab at it, from working with promises.

(Disclaimer: JS noob, coming from the Python world. Even there, currying is not used all that much, but it can come in handy on occasion. So I cribbed the currying function - see links)

First, I am starting with an ajax call. I have some specific processing to do on success, but on failure, I just want to give the user the feedback that calling something resulted in some error. In my actual code, I display the error feedback in a bootstrap panel, but am just using logging here.

I've modified my live url to make this fail.

function ajax_batch(e){
    var url = $(e.target).data("url");

    //induce error
    url = "x" + url;

    var promise_details = $.ajax(
        url,
        {
            headers: { Accept : "application/json" },
            // accepts : "application/json",
            beforeSend: function (request) {
                if (!this.crossDomain) {
                    request.setRequestHeader("X-CSRFToken", csrf_token);
                }
        },
        dataType : "json",
        type : "POST"}
    );
    promise_details.then(notify_batch_success, fail_status_specific_to_batch);
}

Now, here in order to tell the user that a batch failed, I need to write that info in the error handler, because all it is getting is a response from the server.

I still only have the info available at coding time - in my case I have a number of possible batches, but I don't know which one has failed w.o. parsing the server response about the failed url.

function fail_status_specific_to_batch(d){
    console.log("bad batch run, dude");
    console.log("response.status:" + d.status);
}

Let's do it. Console output is:

console:

bad batch run, dude utility.js (line 109) response.status:404

Now, let's change things a bit and use a reusable generic failure handler, but also one that is curried at runtime with both the known-at-code-time calling context and the run-time info available from event.

    ... rest is as before...
    var target = $(e.target).text();
    var context = {"user_msg": "bad batch run, dude.  you were calling :" + target};
    var contexted_fail_notification = curry(generic_fail, context); 

    promise_details.then(notify_batch_success, contexted_fail_notification);
}

function generic_fail(context, d){
    console.log(context);
    console.log("response.status:" + d.status);
}

function curry(fn) {
     var slice = Array.prototype.slice,
        stored_args = slice.call(arguments, 1);
     return function () {
        var new_args = slice.call(arguments),
              args = stored_args.concat(new_args);
        return fn.apply(null, args);
     };
}

console:

Object { user_msg="bad batch run, dude. you were calling :Run ACL now"} utility.js (line 117) response.status:404 utility.js (line 118)

More generally, given how widespread callback usage is in JS, currying seems like a quite useful tool to have.

https://javascriptweblog.wordpress.com/2010/04/05/curry-cooking-up-tastier-functions/ http://www.drdobbs.com/open-source/currying-and-partial-functions-in-javasc/231001821?pgno=2

JL Peyret
  • 10,917
  • 2
  • 54
  • 73
0

I agree that at times you would like to get the ball rolling by creating a pseudo-function that will always have the value of the first argument filled in. Fortunately, I came across a brand new JavaScript library called jPaq (http://jpaq.org/) which provides this functionality. The best thing about the library is the fact that you can download your own build which contains only the code that you will need.

Clarence Fredericks
  • 1,247
  • 1
  • 7
  • 4
0

I asked a similar question at https://softwareengineering.stackexchange.com/questions/384529/a-real-life-example-of-using-curry-function

But only after I use ramda do I finally appreciate the usefulness of curry. So I will argue that if we need to chain functions together to process some input data one step a time, e.g. the promise chain example in the article Favoring Curry, using curry by "function first,data last", the code does look clean!

Qiulang
  • 10,295
  • 11
  • 80
  • 129
0

Here you have a practical example of were currying is being used at the moment. https://www.joshwcomeau.com/react/demystifying-styled-components/

Basically he is creating a poor man styled components and uses currying to "preload" the name of the tag when creating a new style for it.