Really nice to see that there's now an auto-curried, function-first version, lodash-fp! I've been really attracted by Ramda JS recently for this reason.
I've been looking for some real-world examples of how currying might be useful in javascript. Haven't not used a language which supports currying for any real world project, I'm interested to know how it can help.
I found a page [1] which talks about currying in javascript, then says "Are there practical uses for currying in JavaScript? Not really."
Can you point me at anything which will help me see why it's useful?
var predicateListFunc = function(props) { return R.allPredicates(R.map(R.curry(R.eqProps), props)); }
var compareProperties = R.unapply(predicateListFunc);
var mergeLists = R.unionWith(compareProperties("Property1", "Property2"));
var groupById = R.groupBy(R.prop("Property1"));
var getGroups = R.compose(R.toPairs, groupById, mergeLists);
var groups = getGroups(list1, list2);
With this code I can merge any two lists (list1 and list2) on any two properties (Property1 and Property2), and then group the result. I use this to synchronize client and server data.
I don't know if this answers your question, since I wrote in about an hour of learning Ramda.js, and there might be an easier way of doing it.
This slideshow [1] by one of the authors of Ramda.js goes over a JavaScript example in OO style and refactors it to functional style. Currying is used to complete the refactoring.
I've linked to the slides on currying but you'll need to back up to follow the whole example.
Wow, thanks, that presentation is pure gold! The best thing about FP (and moving into it from the OOP world) I've ever seen: clear, easy to follow, based on a practical example and really presenting the sense behind the use of FP.
There is an excellent talk called "Underscore, you're doing it wrong!". The talk explains how well designed param order with currying leads to very short and expressive code -- and how underscore missed the boat. This aspect of it should be interesting as it's related to this post. It's well worth the watch.
I was just about to post exactly this. Well worth a watch. It was this talk which finally made currying "click" for me. And serendipitously the topic is the improvements currying and swapping args can make to the underscore (or lodash!) API.
I even tweeted to @jdalton on announcement "hey lodash, you're doing it right" :)
One situation where I felt compelled to use lots of currying was when I was working with a promise library for async code. There are lots of little callbacks you need to use and you benefit from having combinators that act as function versions of js operators, like "+", "[]" and so on and currying helps cut down on the number of combinators you need.
That said, I didn't end up being a big fan of it in the end. Other people can get confused by the new abstractions the combinators introduce and whenever you pass the wrong number of arguments to a function you end up with very tricky runtime errors (this isn't an issue in Haskell because the type system checks this for you)
Its been a while since I worked with this so this is kind of a shitty example out of the top of my head:
If you have code that looks like this:
var user_list =
fetch_json()
.then(function(data){
return data.users
})
You can write it more succinctly using a combinator library instead of writing the callback out by hand:
var user_list =
fetch_json()
.then(get('users'))
Similar things also apply on other code that uses callbacks like maps, filters, etc. I also had combinators for other common JS operators (set, "+", "==", ...)
The point where currying comes in is that it lets you define a single "get" function instead of a separate versions for one and two arguments:
//curried
x = get('users', data)
y = get('users')(data)
//non curried
x = get2('users', data)
y = get1('users')(data)
That said, there are some downsides to using combinators instead of writing the callbacks by hand. If you need to debug something the stack traces are harder to follow and currying doesn't play nice with functions like Array.prototype.forEach that pass "extra" parameters to the callbacks.
In the end the feeling I got was that trying to make JS more functional is not worth the trouble. If I could go back I would try to replace the promises with something less intrusive in terms of coding style, such as generators/coroutines.
Yes, I think I've come to the exactly same conclusions in the past, both with regard to promises and curried (or partially applied functions for that matter).
This may only apply to me but I've found that without strong, static typing to help out, my brain starts to melt sometimes trying to workout what heavily curried JS functions actual do without using a debugger.
"A programmer’s pipe-dream is to write code, and be able to use it repeatedly with little effort. It’s expressive because you write in a way that expresses what is needed, and it’s reuse because.. well, you’re reusing. What more could you want? Curry can help.":
It makes the syntax a bit better for combining functions. Seems like a small thing, but with all the complaining about nested callbacks I guess it's good. See Ramda, who came up with this concept, for a deeper discussion of the benefits.
I found a page [1] which talks about currying in javascript, then says "Are there practical uses for currying in JavaScript? Not really."
Can you point me at anything which will help me see why it's useful?
[1] http://benalman.com/news/2012/09/partial-application-in-java...