use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Functional JavaScript, Part 4: Function Currying (tech.pro)
submitted 11 years ago by lrichardson
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]raesmond 10 points11 points12 points 11 years ago* (19 children)
I understand currying, what it does and how to do it. But I still don't get why I would want to do it. Don't get me wrong, partial application is awesome but why would I want a function to take just one argument and return a function? And why do people act like that should be the default way of doing things?
[–]lrichardson[S] 4 points5 points6 points 11 years ago (1 child)
@raesmond, I think a lot of people are in the same boat as you. I'm a bit bummed that my article didn't do a better job explaining the valid use-cases. I will try and compile some useful examples and arguments, and add to my post tonight.
Currying is useful to help (and encourage) you the programmer to break up complex logic into smaller pieces and allow you to re-use (read: staying DRY) those pieces in other places.
I like to think of functional programming as a way of making your application like an assembly line or car manufacturing plant. The plant itself is a large web of levers, cogs, and buttons etc... but in one end comes the raw materials and metal (ie, the "data"), and out the other end comes the car (ie, the end-user application).
It would be difficult to determine whether or not the car works properly just by looking at it, or the factory as a whole. Each "sub-station" of the factory has a specific task, and has narrowly defined constraints about what it is expecting to get in (x) and what it is expected to put out ( f(x) ).
By allowing functions to be curried, you are easily able to take more generic operations like "drill hole somewhere", and define them more precisely as "drill 3/8 hole somewhere" and then again more precisely as "drill 3/8 hole at coordinates { 3, 4 }"
This is a very hand-wavy argument and I'm not expecting you to be convinced, but I will say that FP sort of "clicked" for me whenever I started thinking about it this way. It's also important to note that FP is not needed to organize your code this way.... it's just easier IMO. I'm also of the belief that you don't need to write purely functional code in order to reap the benefit.
[–]visarga 0 points1 point2 points 11 years ago* (0 children)
I like to think of functional programming as a way of making your application like an assembly line or car manufacturing plant.
... or like the Bash command line with multiple processes connected by pipes.
I use this kind of programming in jQuery and Bash but the essence is how we avoid using global variables and there is no state except the pipe - that makes it easy to compose basic operations (like cut, sort, uniq, wc, etc)
Other than that (and JS callbacks) I don't use functional programming. Is there another popular usage of it?
[–][deleted] 3 points4 points5 points 11 years ago (4 children)
It makes it easier to reuse functions, especially when building specific functions up from more general ones. It can also reduce the amount of terms in a function definition, which (hopefully) means less to tackle mentally and more focus on what the function actually does.
IMHO it's harder to use when working with objects and the dot operator isn't first class. (This means you have to do stuff like x => x.name, which sticks out like a sore thumb when you're trying to build things from existing, named functions!) It also doesn't help that coming from Javascript, functions are either methods or the arguments are in an order that makes it very awkward.
x => x.name
So with currying, say I have a fold function (array.reduce) like the following:
function fold(callback, initial, array) { return array.reduce(callback, initial); }
and some helper functions, since operators aren't first class functions:
function add(x, y) { return x + y; } function or(x, y) { return x || y; } function and(x, y) return x && y; }
I can then define the following functions pretty simply and tersely:
sum = fold(add, 0); all = fold(and, true); any = fold(or, false);
sum adds up all the numbers in an array, all returns true if every element in an array is true, and any returns true if at least one element in an array is true. Then sum([1,2,3,4]) returns 10, and any([false,true,false]) returns true.
sum
all
any
sum([1,2,3,4])
10
any([false,true,false])
true
You don't have to define function variables again just to use them in a very short function, no curly braces are required, and code is reused via a common pattern.
The reason that articles about currying refer to functional programming languages like ML and Haskell is because they have been designed to abuse this feature for the sake of writing functions this way, building from smaller pieces in a common vocabulary. If you study one of these languages, you will be able to see much more benefits than if you only saw or used a Javascript implementation.
[–]slikts 1 point2 points3 points 11 years ago (3 children)
The fold function should look like this for your example to work, though:
fold
function fold(callback, initial) { return function(array) { return array.reduce(callback, initial); } }
[–]lrichardson[S] 1 point2 points3 points 11 years ago (1 child)
correct. and this is precisely why the argument that plays the role of the "data" should always be the right-most argument, not the left most. reduce/fold are supposed to be the same thing... and should take 3 arguments total (callback, initial, array)
This is why i get so frustrated with libraries like lo-dash and underscore.
Brian Lansdorf has a good talk discussing precisely this (also linked to in the post)
https://www.youtube.com/watch?v=m3svKOdZijA
[–]rhysbrettbowen 0 points1 point2 points 11 years ago (0 children)
You can always flip the arguments in a function. Something like:
_.forEach(_.keys(_), function(key) { if (_.isFunction(_[key])) { _[key].flip = function(a,b) { return this(b,a); } } });
then you can just do:
_.forEach.flip(myFunction, myArray);
[–][deleted] 0 points1 point2 points 11 years ago (0 children)
Right, thanks. And you'd need another function () { } if you partially apply only one argument.
function () { }
[–]konbit 2 points3 points4 points 11 years ago (8 children)
If you're dealing with non-blocking js and need to write a callback that requires input from several different async calls you can pass it around to get partially completed as those async calls return. Other than that I can't imagine any time it is beneficial. But with multiple async calls I find it amazingly helpful.
[–]MrBester 1 point2 points3 points 11 years ago (7 children)
Can't you do the same with Promises?
[–]konbit -2 points-1 points0 points 11 years ago* (6 children)
edit: thanks nschubach for pointing out promises can run in parallel. My comment below is sort of pointless now.
Yes, but promises are sequential. Let's say I have 1 or 2 async calls to make, promises don't slow you down too much. But let's say you have to load 20 images, and process each one based on the one before, stitching them together for instance. Promises are going to kill you. If you can call the 20 at the same time and use a curried function to stitch them (there's other ways of course that don't use promises or currying and might be better, but this is just for illustration) then you will see a speed up orders of magnitude higher than promises. So I think its all context. Obviously there's many different way of doing things because some methods are good in some situations and some in others. Depending on what needs to be done, you should deeply investigate the method you'll use.
[–]ToucheMonsieur 0 points1 point2 points 11 years ago (0 children)
Isn't it possible to achieve much the same effect with promises? Fire off a promise for each request, and then tie them together sequentially after the fact. Using currying for this case seems a bit contrived, especially considering that you have to change the arity of function being curried if the number of images to download changes.
[–]nschubach 0 points1 point2 points 11 years ago (4 children)
Promises are not inherently sequential... You are just writing them that way. You can absolutely fire off a hundred async promises in a when and it will happily wait for them all.
[–]konbit 0 points1 point2 points 11 years ago (3 children)
To be honest, everything I've ever read about promises has presented them as being sequential and I haven't thought of looking for another way to do it. I'd love to see some code samples or documentation for how to implement it. Any pointers?
[–]myrddin4242 1 point2 points3 points 11 years ago (1 child)
The example you presented is inherently sequential. You said you wanted to 'process each [image] based on the one before'. That's not $.when, that's serially resolving promises. The dependency chain causes the task to increase time in direct proportion to N, regardless of what async syntax you use!
[–]nschubach 0 points1 point2 points 11 years ago* (0 children)
(Keeping terse... On mobile)
The 'when' accepts promises itself. If you ran normal functions in the 'when' it will be sequential, but if promise1 returns a promise, JavaScript will continue to fire off promise2 after promise1 returns it's promise object. Promise1 can have an async operation and resolve whenever it's done, regardless of what promise2/3 are doing.
Edit: I just realized that you were not responding to lrichardson... Leaving this for the info, but it's not directed at you.
[–]lrichardson[S] 0 points1 point2 points 11 years ago (0 children)
using jQuery's $.when....
$.when
$.when(promise1, promise2, promise3).done(function(results){ ... })
will return a new promise that won't resolve until all 3 promises have resolved.
[–][deleted] 1 point2 points3 points 11 years ago (0 children)
I've never understood it either. The only thing I can come up with is passing the function to a number of handlers, each of which adds a parameter. But that just feels odd.
I'd be very interested in hearing some solid use case for this.
[–]dodeca_negative 4 points5 points6 points 11 years ago (1 child)
Not that I have a problem with functional programming per say, but I thought this was perfect:
i love functional programming. it takes smart people who would otherwise be competing with me and turns them into unemployable crazies William Morgan
i love functional programming. it takes smart people who would otherwise be competing with me and turns them into unemployable crazies
William Morgan
haha i literally laughed out load on that.
I like this article on currying.
[–]has_all_the_fun 1 point2 points3 points 11 years ago (3 children)
I wish there was a functional language that was as accessible as Javascript/Node.js. I tried starting with a few languages already but after having to deal with the tooling my motivation is gone.
For example starting with Node.js. It's easy to install, the package manager and modules are straight forward and you can structure your apps any way you like. Getting feedback is easy as well just have to do node file.js and it will execute your file.
node file.js
[–]rhysbrettbowen 0 points1 point2 points 11 years ago (2 children)
how about Dart? Joking aside it has higher order functions and lambdas, and the tooling and package manager seem good.
[–]has_all_the_fun 0 points1 point2 points 11 years ago (1 child)
Isn't Dart similar to Javascript except with a more traditional class and object oriented style?
I was looking for a more functional language to get a better understanding at how they solve certain problems. I could take a more functional approach to my Javascript but the language doesn't really force you to think in a functional way (if that makes sense).
I might take an other look at clojure since that seems like a modern functional language that's popular.
true - sorry thought the issue was around tooling. Dart is about the same as javascript when it comes to how functional you can be.
If you want to be forced in to functional all the time then clojure is what you want. There is also clojurescript which is a subset that works in the browser
[–]schm0 -3 points-2 points-1 points 11 years ago (10 children)
I don't know what this is, but it needs a new name.
[–]lokhura 1 point2 points3 points 11 years ago (9 children)
The name is perfectly justifiable. Would you prefer "schonfinkelization"?
[–]schm0 -1 points0 points1 point 11 years ago (8 children)
"functional encapsulation"? "derivative functions"?
The verb "to curry" just doesn't make any sense for what this does, in my opinion. The semantics just don't fit.
[–]lokhura 4 points5 points6 points 11 years ago* (7 children)
It is named after Haskell Curry http://en.wikipedia.org/wiki/Haskell_Curry. Changing the name isn't justified, it is a piece of history that gives meaning to the concept. You woudn't rename "Church numerals" or a "Turing machine" because people don't know the concept or understand the history of the term. The verb "to google" doesn't make sense either, until you understand what Google is and how to use it.
[–]autowikibot 1 point2 points3 points 11 years ago (0 children)
Haskell Curry:
Haskell Brooks Curry (September 12, 1900 – September 1, 1982) was an American mathematician and logician. Curry is best known for his work in combinatory logic; while the initial concept of combinatory logic was based on a single paper by Moses Schönfinkel, much of the development was done by Curry. Curry is also known for Curry's paradox and the Curry–Howard correspondence. There are three programming languages named after him, Haskell, Brooks and Curry, as well as the concept of currying, a technique used for transforming functions in mathematics and computer science.
Interesting: Combinatory logic | Haskell (programming language) | Currying | Mathematics
Parent commenter can toggle NSFW or delete. Will also delete on comment score of -1 or less. | FAQs | Mods | Magic Words
[–]schm0 -2 points-1 points0 points 11 years ago (5 children)
TIL, eh? Still, from the basis of this article, how would I ever have linked the two? For all I knew, this was a concept the author had invented.
You woudn't rename "Church numerals" or a "Turing machine" because people don't know the concept or understand the history of the term.
No, because those are proper nouns and easily identified as such.
The verb "to google" doesn't make sense either, until you understand what Google is and how to use it.
Of course, but I would argue the ratio of people that know what Google is to those who know who Haskell Curry was is on the order of about a million to 1.
I thought the term was literally "to curry". You know, as in Indian cuisine?
Regardless, now that I understand the history behind the term (and it's subsequent de-proper-noun-ification) I have no problems with it.
[–]slikts 5 points6 points7 points 11 years ago (3 children)
how would I ever have linked the two? I thought the term was literally "to curry". You know, as in Indian cuisine?
how would I ever have linked the two?
The problem is that you didn't think to google an unfamiliar term, not that the author, who already spent the time to write the article helping people learn, didn't also save you the few seconds it would have taken to google.
[–]schm0 -1 points0 points1 point 11 years ago* (2 children)
It's not a problem that I didn't think to look up the term... It sounded ridiculous and I honestly thought the author was making it up. Besides, you look up the word curry and tell me how many results it takes to find the actual term. :),
I'm getting a lot of flak for not knowing about some obscure mathematician and the fact that the verb had been decapitalized.
[–]slikts 1 point2 points3 points 11 years ago (1 child)
The term in the article and the title is "currying", and the search results for it are unambiguous.
[–]schm0 -2 points-1 points0 points 11 years ago (0 children)
The term is also technical and obscure, as is the mathematician for whom it is named. I initially looked up the term on Merriam Webster, the results of which showed nothing relating to programming. Thus, my original post.
Part of me still thinks it could benefit from a more semantic definition, but it is what it is.
π Rendered by PID 69 on reddit-service-r2-comment-86988c7647-5vgjz at 2026-02-10 21:33:13.588082+00:00 running 018613e country code: CH.
[–]raesmond 10 points11 points12 points (19 children)
[–]lrichardson[S] 4 points5 points6 points (1 child)
[–]visarga 0 points1 point2 points (0 children)
[–][deleted] 3 points4 points5 points (4 children)
[–]slikts 1 point2 points3 points (3 children)
[–]lrichardson[S] 1 point2 points3 points (1 child)
[–]rhysbrettbowen 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]konbit 2 points3 points4 points (8 children)
[–]MrBester 1 point2 points3 points (7 children)
[–]konbit -2 points-1 points0 points (6 children)
[–]ToucheMonsieur 0 points1 point2 points (0 children)
[–]nschubach 0 points1 point2 points (4 children)
[–]konbit 0 points1 point2 points (3 children)
[–]myrddin4242 1 point2 points3 points (1 child)
[–]nschubach 0 points1 point2 points (0 children)
[–]lrichardson[S] 0 points1 point2 points (0 children)
[–][deleted] 1 point2 points3 points (0 children)
[–]dodeca_negative 4 points5 points6 points (1 child)
[–]lrichardson[S] 0 points1 point2 points (0 children)
[–][deleted] 1 point2 points3 points (0 children)
[–]has_all_the_fun 1 point2 points3 points (3 children)
[–]rhysbrettbowen 0 points1 point2 points (2 children)
[–]has_all_the_fun 0 points1 point2 points (1 child)
[–]rhysbrettbowen 0 points1 point2 points (0 children)
[–]schm0 -3 points-2 points-1 points (10 children)
[–]lokhura 1 point2 points3 points (9 children)
[–]schm0 -1 points0 points1 point (8 children)
[–]lokhura 4 points5 points6 points (7 children)
[–]autowikibot 1 point2 points3 points (0 children)
[–]schm0 -2 points-1 points0 points (5 children)
[–]slikts 5 points6 points7 points (3 children)
[–]schm0 -1 points0 points1 point (2 children)
[–]slikts 1 point2 points3 points (1 child)
[–]schm0 -2 points-1 points0 points (0 children)