Currying - Part 6 of Functional Programming in JavaScript
Vložit
- čas přidán 16. 08. 2015
- 💖 Support the show by becoming a Patreon
/ funfunfunction
A short video explaining the concept of curring, using JavaScript. This is part of a series, where are learning functional programming using JavaScript.
Currying is when a function, instead of taking all arguments at one time, takes the first one and returns a new function that takes the second one and returns a new function which takes the third one, and so forth, until all arguments have been fulfilled.
Curry function in lodash:
lodash.com/docs#curry
Playlist of full series
• Functional programming...
You want to follow me on Twitter and Quora:
/ mpjme
www.quora.com/Mattias-Petter-J...
💛 Follow on Twitch
We record the show live Mondays 7 AM PT
/ funfunfunction
💛 Fun Fun Forum
Private discussion forum with other viewers in between shows. www.funfunforum.com. Available to patron members, become one at / funfunfunction
💛 mpj on Twitter
/ mpjme
💛 CircleCI (Show sponsor)
Robust and sleek Docker-based Continuous Integration as a service. I used CircleCI prior to them becoming a sponsor and I love that their free tier is powerful enough for small personal projects, even if they are private. Use this link when you sign up to let them know you came from here:
circleci.funfunfunction.com
💛 Quokka (Show sponsor)
Wonder how MPJ evaluates JavaScript inline his editor. Quokka is the answer - use this link when you buy to let them know you came from here:
quokka.funfunfunction.com
💛 FUN FUN FUNCTION
Since 2015, Fun Fun Function (FFF) is one of the longest running weekly CZcams shows on programming 🏅 thanks to its consistency and quality reaching 200,000+ developers.
🤦♂️ The Failing Together concept is what makes FFF unique. Most coding content out there focus on step-by-step tutorials. We think tutorials are too far removed from what everyday development is like. Instead, FFF has created a completely new learning environment where we grow from failure, by solving problems while intensively interacting with a live audience.
Tutorials try to solve a problem. Failing Together makes you grow as a developer and coworker.
📹 Each show is recorded live on Twitch in a 2-hour livestream on Mondays. The host, assisted by the audience, is tasked to complete a programming challenge by an expert guest. Like in the real world, we often fail, and learn from it. This, of course, reflects what the audience identifies with, and is one of the most praised aspects of the show.
⏯ On Fridays, an edited version of the show is adapted for and published on CZcams.
Content Topics revolve around: JavaScript, Functional Programming, Software Architecture, Quality Processes, Developer Career and Health, Software Development, Project Management - Věda a technologie
I woke up this morning and thought "Ugh, it's Monday". And then I thought "Yay! It's Monday!"
Thanks for improving Mondays :)
Wow, what a cheery comment! Thank you so much!
function thankYouMessage(name) {
return function(reason) {
console.log(name + ', Thank you for ' + reason);
}
}
var thankFunfunfunction = thankYouMessage('+funfunfunction');
thankFunfunfunction('improving my Mondays as well!');
Hey, what would be diffrent if I would use that?
function thankYouMessage(name,reason) {
console.log(name + ', Thank you for ' + reason);
}
thankYouMessage('funfunfunction','improving my Mondays as well!');
why are closures useful for?
0:35 Great quote. Indeed.
"Does it sound confusing? Good! The feeling of confusion is your friend, it means you're learning."
Thanks for this great video! I teach Programming Languages, and you explain currying much better than I did. One of my students recommended your video, and I'm recommending it to the rest of them. I like both the content and the attitude.
That moment when you finally realises how this stuff works and your mind explodes
still waiting for that moment. I want that moment
For me it came at around 6:49 when he removed the 'x =>' part that is so much associated with map/reduce/filter function be it in python, js or scala. And instead he just passed a function!!
also blown my mind exactly at that point
I think he was passing a function previously also :) But after currying, our callback fn is returning something itself without needing second argument. This is why we don't need a fn (having x here) and a return statement (with fat-arrow =>). Am I right +funfunfunction?
BTW, great, funny, simple videos. Your videos are a great starting point to dig the subjects.
@@AnshumanVenkatesh That is exactly the point where my brain stopped working. I think I need to take the red pill that Neo took in the Matrix...
in ES6 without lodash or any deps:
const dragons = [
{ name: 'fluffykins', element: 'lighting'},
{ name: 'noomi', element: 'lighting'},
{ name: 'karo', element: 'fire'},
{ name: 'doomer', element: 'timewrap'},
];
const hasElement = (element) => (object) => {
return object.element === element;
};
const lightingDragons = dragons.filter(hasElement('lighting'));
console.log(lightingDragons);
const hasElement = (element) => (obj) => obj.element === element;
So does filter method implicitly invokes a consequent call with an array item as an argument?
dragons.filter( hasElement('lighting') *(x)* )
@Yevgeny The result of hasElement('lighting') is "function(object) { return object.element === element }" (or with ES6 arrow functions : "obj => obj.element === element" ) . That's is what filter expects to work.
You can even omit the parentheses and braces.
const *hasElement* = element => object => object.element === element
@Yevgeny I had the same question/confusion. For me, writing code inside filter's invocation caused me to forget that hasElement() is a *parameter* and not invoked immediately.
I think the problem is in how I read the code. It is NOT "filter the dragons array with hasElement()" but instead read it as "the filter function will use hasElement() to filter the dragons array". (take it or leave it)
These sessions are really good. The tricky part is being able to proactively put all of the pieces together in a design pattern to build an application. I'd love to see an "end to end-ish" reference architecture / design pattern & demo application that incorporates your approach to functional programming & object composition.
First time I saw somebody showing a "real" example for currying!
Thanks @mpjme
8 years has passed and nothing changed - yet it is a rarely good example. Though not even real.
5 videos ago in this playlist: "Yes, I understand this!"
5 minutes into this video: "Brain, please compute..."
That's what I was thinking. The first part parts of this playlist ... yep, makes sense ... and then this one ... what the heck is this magic.
Я так понимаю filter ожидает ссылку на функцию, а при каррировании получается что hasElement('lightning') возвращает ссылку на функцию + аргумент в замыкании. Видимо явно вызов выглядит как-то так:
dragons.filter( (function (x) => x.element === 'lightning')(dragon) )
Может иногда будет иметь смысл подготовить промежуточный вариант:
const hasFire = hasElement('fire')
dragons.filter( hasFire )
@@unev as if just understanding the code in English wasn't enough o__o
"confusion is learning" Loved it! I'm going to used this with my kids! Great presentation and explanation.
This is so awesome. I just wrote my first curry function based on some other code, then came over here to understand ‘why’ I wrote it like that. I love how you take the time to explain the reasoning behind the methods.
Finally!!! It's Monday again!! Always the best way to start the week! thanks.
Great video! Thanks for making these, they are very helpful for understanding less talked about topics in javascript.
Thanks for these tutorials, they are truly mind expanding! Very well taught as well as entertaining.
Just remembered how this video introduced this concept to me and changed how I code. I have enjoyed teaching it to people so they don't have to pass the same parameters to functions constantly. Thank you.
Best explanation of currying!! Mind exploded about two minutes in when it clicked.
Wow you are incredibly talented at explaining tough concepts. Great job man seriously keep them coming please!
“The feeling of confusion is your friend it means that you are learning” Great quote !
Seriously, I love the way you explain things. Your mind is crazy awesome. I love how it works. Keep the videos coming! Subscribed and liked a few episodes ago. :)
That was amazing! I am learning curried functions in SML, this video was such a help to get the concept. Thank you so much.
Thanks for explaining currying! It's taken quite a while to grasp how essentially simple it really is. You're video really secured this.
The lack of brackets and semicolons in your code is both exciting and terrifying at the same time.
watching this almost five years later and your explanation was very helpful! Thank you!
I miss your video’s Monday morning is just not the same. Your videos are pure gold and new dev’s are find the help they need still thanks to you
You made me understand "Currying and Closure" which I did not understand easily before! Thank you so much! I'm sure that I will learn a lot of stuffs thanks to you!
Yeah, I agree with everyone else! Great video on a complicated topic, I think this topic and my Dyslexia have major issues but this was the best video on this topic. I feel like he is done with this channel now because no new videos in a year or he is focusing on patreons, which is fine, there is a lot of content going back 6 years, so I can understand. Thanks again. Even the background music was perfect!
So, why use currying instead of a regular function ? What does it accomplish ?
-Jean-Baptiste Bouhier modularity. Rather than having one quite rigid function you can swap every part/operation with the new one. And if needed you can apply multiple different functions to the same thing quite easily. If you checked any more stuff about functional programming and even mpj's previous videos, in functional programming you sort of build your toolbox of functions which you can reuse across the different projects. So than you can curry your functions you can chain them up quite easily.
partial application
"Currying is related to, but not the same as, partial application." - en.wikipedia.org/wiki/Currying
From my understanding, having a Curry'd function is better than having a "normal" function when you don't know exactly what all the parameters are of the functions. Having a Curry'd functions means that you can pass one parameter into the function before working out what the other parameters will be
OK, I believe you. I didn't believe in functional programing until I had to work through an example. Does anyone know of a good place where there is an example that shows the use of it in contrast to something that is inferior? The example of an improvement in this video is a little contrived.
(I should add that I feel like it is a great video otherwise. This is my first time coming across this concept and I feel like I get it. The only thing is that I am not sold out into how could it improve my functions. One word answers and simple examples help you know the why, but not necessarily to understand the why.)
So glad I stumbled across your vids. I am currently falling in love with javascript because functional programming
Thanks again! Great video, as always! Great refreshed to currying.
I've used the curry function before but haven't realized that it could be more powerful when passed as an callback function to the filter
this is awesome
Im at 3:40 and bracing myself for the inevitable 'this allows you to make things more COMPOSABLE' speech. :-) Maybe its just me but ever since I saw him say that in a video a few weeks back, it has resonated. These chunks of code are now like legos to me. Mind blown.
These videos are sooo good, thank you so much for sharing!
Your videos have been a fantastically thorough resource to help me learn some of these intermediate - advanced JS concepts, so thank you for that. But I read through the comments here and saw that you, yourself don't use currying and only sometimes use partials. I watch these videos not only because I trust what you're telling me is true, but also because I trust that what you're teaching is worth learning. Just wanted to be a voice in this discussion. Thanks for your instruction and keep up the great work!
+Matt McDaniel Actually use currying more after this episode. :) Ramda.js is very addictive. That said, I agree - I think I did a bit of mistake with the currying episode, because I did it was what the majority asked for rather than something that I was personally excited about.
You are a strange and crazy person; I love it! This was a great video that simplified currying to a level even I can understand. You're a wizard!
You have a really good way of explaining things and presenting them to people. Really appreciate the effort you put in creating all this valuable content.
+Adrian Oprea Thanks a ton for your kind words, really motivates me to keep on going!
You're amazing man :) You make me laugh, learn and get excited about coding. Thank you so so so much
TY for this video MPJ! really helped me out with this one.
love this video. informative and super entertaining. well done!
This one is not so easy! Gonna have to re-watch it and try myself before wrapping my mind around it! Thanks a lot!
Yeah, I know it's a bit tricky this one. Currying is just one of those things that you have to go a little bit yourself to truly get.
+funfunfunction To be honest, you using ES6 did not really help. :) But, thank you anyway. :)
I am a simple Indian, I see curry, I press like. :D
i love to code and i even love it more because mpj is teaching me how to code.
Best learning experience so far. Thanks a lot
Your videos are amazing. They answer all the questions that I have :-)
I have no idea why I am watching this video I’m done with finals but somehow you made fucking currying interesting. Wish I would have found this channel earlier this semester. Hope ur channel grows!
You are so entertaining! I'm an instant fan.
Man, you are the best :) just implemented in different scope :)
function init(name) {
alert(name);
return function displayName(verb) {
alert(verb);
return function me(praise) {
alert(praise);
}
}
}
init("MPJME")("is")("kool...:)");
Hey there, I found your channel about a week or so ago and I must say it is probably the most entertaining programming channel I've ever visited. You clearly know the material and explain it in an authoritative (and humorous) way. Definitely subscribing and will continue to watch new videos each Monday.
I did have one question in regards to this video. You mention that one of the strengths behind currying is the ability to build up a function's arguments incrementally. What is the advantage of doing this over just simply using a specification object as a function's argument and passing that around to add properties to it?
mpjme, thank you for the easiest and best explanation of currying!
+Екатерина Дмитрук Thanks a ton - that's so nice of you say.
Thank you because thanks to you I learned finally currying! Im grateful bro, I hope you are okay and soon will makw videos for us, you can explain so simple and nice, its very awesome!
Very helpful and entertaining! Thanks!
MPJ, you're the man. I always check out your videos when I need to brush up on a topic. With that being said, how come you used arrow functions but not template literals in this video?
Tks a lot. Great serie of videos !
Superb explanation, thanks!
what’s more important is to understand that all this is made possible because of closures. A function returned by another function will not have access to its parent scope variable environment in its execution context unless it “closes” that environment when it’s function is called.
Brilliant video, thanks!
Nice video. Thanks for that.
I've never known that there is a `partial` and `currying` functions in lodash.
I've been using `bind` all the time for that. As you mentioned in the comments `currying` and `partial` are different, and it would have been nice if you'd mentioned it in the video and elaborate on it. Because when I used `bind` I though I was doing currying, and I believe lots of people confuse them too.
Man you slayed this! Thanks!
Thanks! These videos are so nice
You're an amazing teacher, please come back! 😍
Hi MPJ, awesome videos, thank you !
One observation though : at line 14, I think we need to pass (x) as well:
// Original :
let hasElementCurried =
_.curry( (value, obj) => obj.element === value )
let lightningDragons =
dragons.filter(x => hasElementCurried('lightning')) // hasElementCurried('lightning')(x)) //
My heart is happy 🌿
+Joshua Gish LOL!
thx man finally understood the concept !!
I think I understand "how" this works, but I can't say this jumps out at me as being particularly useful or more readable.
Good work mpj!
Great explanation, thank you!
Thanks, great video!
Thanks for the explanation of currying
MIND. BLOWN!!!!
HI!
While I still don't know that I'll find many use cases for Curry (or Partial) for that matter, at least I finally understand it! (to put this in perspective, I've been coding for 10+ years and regularly use some amount of functional programming in my everyday work... I've just never quite grokked currying despite the pages and pages I've ready about it)
Excellent explanation!
These are really great thanks!
I love this guy!
For all of you who still don't know why the hasElement function doesn't have x argument passed.
Filter method when called on array doesn't need said x argument as it's optional overwrite of 'this' which at the time the array that the filter method was invoked on (look up on mdn)
Curring with filter is very, very cool :D
Can you show more useful and real examples?
Thanks for the great series.
It's very well balanced for the newcomers and people with some background.
Please make more real case examples making the new info more useful! :)
very good, still hard to see myself refactoring code daily using currying.... But its good to know it since its a frequent topic in JS interviews! :D
i was planning on spending the day figuring out currying, now i just need to figure out what to do with the rest of my day!!! :)
amazing tutorial thank you very much!
Excellent explanation.
Enlightening Monday!!!
Here is an ES5 version for the same, for understanding purpose.
var dragon = function(name) {
return function(size) {
return function(element) {
return name + " is a " + size + " dragon that breathes " + element + "!";
}
}
}
var output = dragon("karo")("large")("ice");
console.log(output);
I think its worth mentioning partial in the context of currying. Thanks for the great video.
Samuel Ytterbrink Yeah, I had that in there first but the video got really long and it was hard to get coherent. Might do another one on that.
mpjme +1 on another video on Partials :-)
I've almost wrapped my head around currying but still don't quite see why to do it.
Thanks for your vid's.
Thanks, helped me grokk currying a little better. Would like to see a less contrived example, since in the case of hasElement, we control the function and could curry it ourselves as `const hasElement => element => obj => obj.element === element`
A great video as always. Thanks for all you do. :) This works for a fixed number of arguments - what if I want to have an indefinite number of function calls though? For example, adding or multiplying a bunch of numbers. Maybe a bad example as it's probably easier to take all the arguments at once, convert them to an array and then reduce, but I'm interested in principle...
I shed a tear for the semicolons lost in this video. :'(
Thanks, very good example
Hi, MPJ,
I think I can manage nice and funny, even though I didn't understand this one well at all. Curry makes me think of "Red Dwarf." My friend Dustin, who introduced me to Fun Fun Function, knows how to manipulate images. I'll research images of Lister, Rimmer, Kryton, and Cat, and try to sum up, briefly, what they'd say in reaction to currying. Dustin can put the elements together.
I'm thinking ...
Lister: Coding? So not me, except for this 'currying' thing."
Rimmer: "Reminds me too much of you, Lister."
Kryton: "I've been doing this all the time, and did anyone ever notice?"
Cat: "Great! Now I'm hungry!"
I actually lol'd at the "post-production leviosa"
Excellent video!
I really love your style, extremely clear and concise.
I noticed that you are using babel-node engine instead of node, because of it's support for ES6.
As ES6 turns Javascript to being even a more functional programming language, it would be interesting, if is possible, for you to cover the functional programming basics (use of constants, pure functions, etc.)
Thank you for your precious time and keep the videos coming =)!!
Thank you! Yes, going down into basics more and more is the idea (immutability and purity are definite future videos) - in fact, that is sort of the idea with the channel in general. A lot of people come into programming tooling-first nowadays, doing quite complicated things with tools, but lack the fundamentals to understand and build those tools themselves. This is where I came from as well. My idea is to move down from tools into computer science fundamentals and designs patterns, and letting other people do framework tutorials.
Thank you for taking time to read (and also reply!!) my comment.
I watched all your videos so far and I really love your approach to teaching, both in the tutorials and the long-term approach that you just explained.
You really encourage people to stay curious, not only by telling them to do it :)
Keep the tutorials coming!! Thank you!!
Thanks for helping learning scala!
Nice video series. Keep it going,
perfect tutorial, it's awesome. thx a lot
An amazing video!
when i watch, Wow! everything is clear. but after finishing the video. my head is warm up and watch the video again. :)
Why can't it be
let lightingDragons = dragons.filter(hasElement('lightning')(x))
I'm using your example of
let output = dragon('Karo')('large')('ice')
Why did you omit the x?
+Shazwi Suwandi Hi
Filter is doing it automatically, a quick example done in the browser
function my_head(x) {
return x == 1
}
my_arr = [0,3,1,2,1,1]
my_arr.filter(my_head);
Array [ 1, 1, 1 ]
As you see, filter called my function and passed it X. That's what happened on the curry.
(x) is done automatically
+Adrián Abreu González Oh I get it now. I was wondering where the x went. Thank you.
Oh I get it now. This comment should go to the top. Almost forgot that you can pass a function value as an argument to filter :)
This is a easy helpful example. Thanks.
Let me just add a comment to this though its been years, that would be absolutely true but the presenter used lodash as opposed to writing the full version as he did in his initial example. In that case writing it out manually you would have to pass the obj as second parameter explicitly.
const hasElement = element => obj => obj.element === element;
const lightningDragons = dragons.filter(d => hasElement('lightning')(d));
console.log(lightningDragons);
This should now work exactly the same as MPJ's lodash example, omitting the argument (d) in this case would make the filter fail.
i've never learned so much in my whole life
"The feeling of confusion is your friend, it means you are learning" LOL
Awesome explanation.Wow
I don't understand this but love it anyway!
+Hoto hahaha I've been watching your comments through all the videos and actually I was thinking the same: this one is not easy but still love it
Well done. Thanks
It`s a bit advanced for me. I'll watch it again. My english isn`t so good yet to get so much details in only one simple watch. Congratulations Mattias Petter Johansson.
Thanks, good to know this stuff.