Currying functions in Javascript is an advanced topic. Once you understand how to curry a function and how to use curried functions, it can be a very useful feature in your code. This tutorial will cover the what, why, and how to's of currying functions in Javascript. All this talk of currying really just makes me hungry! 😂 If you are just learning Javascript, you should start with my full 8 hour course tutorial here: ruclips.net/video/EfAl9bwzVZk/видео.html
Please make more videos about advanced topics and concepts in an easy, digestible way you do naturally. RUclips is filled with too many videos about basic stuff. You'll make a huge difference daring to be different from other youtubers. I enjoyed your explanations so much. Thanks.
I love that timeTen example, I've used currying before but other than to scope variables I didn't see much of a use case for it. The times 10 example really gives me a great reason for caring about it much more as it allows for possible cleaner reusable code. Great video Dave.
I first learnt about the term 'curry' through a Leetcode Javascript qns. Even though curry function is a kind of higher order function, it is still quite hard for me to understand currying through a challenging question. Thanks so much for breaking down the concept of currying starting from a very simple example. I understand it a lot better now!
Thank you for this video. My head has been hurting all day trying to truly understand currying. I don't want to move on before I get the logic behind it. I'm not a 100% but I definitely felt some flashes of understanding while watching your video.
It’s hard for me to understand some concepts. But i understood all of what you had to say about currying. Now i understand currying better than other topics that are alot simpler. Thanks
Man, your video came to me in the exact time! I see for some days trying to understand a debounce function, and was about to ask in SO, but your video made me understand it. REALLY thanks.
Damn dude, I just love the way you teach things. And the knowledge you are giving out to people is just marvellous. A person learns this kind of stuff while working in the industry. Thanks to you for teaching us beginners how things really work.
Dave, thank you very much for all your efforts! I watch your videos over and oveer and every time a new layer of konwledges reveals itself and make me go "WOW!"
Hi Dave, thanks for making this video. I've seen a few vids on currying and I am still wondering is there a situation where currying would be preferred over regular function calls? Or is this really just a stylistic choice?
Great question, Kevin! It is useful when following a functional programming approach - but not necessary as JS does accept more than one parameter in a function (as opposed to Haskell). That said, here is a good quote on the practical application of currying followed by the link to the original source: "Currying is a type of partial function application. We can use its returned functions to make a lighter version of an existing function. It’s helpful when we have many places that use a function with exactly the same way. Our implementation will be shorter and more readable." huynvk.dev/blog/currying-in-javascript-and-its-practical-usage Thanks for asking! 💯🙏
Hey Dave, thanks for your advanced javascript concepts course. You lay down them pretty easily. All of these examples do help a lot, thank you very much!)
I REALLY liked this! Very clear. Thank you so much Dave. I'm off to make curry and recursively walk backwards through my tree data. I may be some time.
I recently started reading O'Reily Books' Learning React. They touch on currying for like a paragraph. This video opens up such a better understanding!
Hey Dave ! Take a look at this problem : We need to write a curried sum finction which can accept any "n" numbers of params and at the end returns the sum of all the params. The catch is that in the end it will receive undefined as a parameter so that it knows to return the sum now : - sum(1)(2)(3)(); // should return 6 sum(1)(2)(); // should return 3 sum(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)() // you get the idea. How can we write something like this ?? Thanks in advance !
Hi Dave, thank you very much. I wished I had found your channel sooner. I have had difficulty understanding this concept and I'm not even a beginner n JavaScript. Thank you very much. I've subscribed and gave the video a big like. I'm hoping to see more exciting and insightful videos.
Wonderful explanation about the concepts of currying, now this concept is totally clear to me, thank you very much @Dave, please keep creating nice videos.
thanks SO much for the excellent content. I've been a web designer and IT person my whole life, but like a lot of 'web designers', JavaScript in the early days was hard, the books were daunting, and I of course am familiar with how to add it too my pages, get it working, and write the most basic stuff. but getting deeply into it, has never been a serious goal. but last year, I was forced to learn to maintain an application written in angular/typescript. so I learned it mostly. and that got me into trying to learn react. the more tutorials in react I started, I realized no. I need to obviously master the language first! so here I am! lol. your videos are really helping me to understand some of the more tricky aspects of JS. so, about currying functions... are these techniques used in modern frontend design very much? if I understood the video correctly, the parameters of the curried functions can be passed in separately. so does that mean at different times in the future? is this somehow related to async/await, or am I thinking about it wrong? I guess I am trying to understand where and how these are used. I guess I'll watch it again lol. thanks again for the amazing content!
You're welcome! When currying, you can create a partial - a function that has not received everything it needs yet. That is different than async / await which I cover in detail here: ruclips.net/video/VmQ6dHvnKIM/видео.html
I think the key to understanding the curry function in this video is the part that uses bind: it creates a function that has part of the arguments "pre delivered". Simple example: the 5 will be automatically put to the add function (add5 is "fixed' with 5): const add = (x, y) => x + y; const add5 = add.bind(null, 5); console.log(add5(10)); // 15 Hope it helps someone, who like me, has rather imperative background and FP concepts are puzzling.
Yes, but saying it is curried or is a curry function gives a more explicit meaning. We have many liquids for example, but saying something is water gives a more explicit meaning.
Great explanation. Question. In the last example, how come the function const total = (x, y, z) => x + y + z when passed as argument as curry(total) and when we get fn.length in curry definition, it gives 3? Shouldn't it give 1 because we have passed function "total" entirely as an arg to "curry" and not (x, y, z) Thanks in advance.
thank you . i liked the way you teach lot. clear , wise and lot of knowledge! for instance you log ' [...args].toString() and. `[args[0]` . these are little things but demonstrate teaching effort of you
Hi, thank you for your great explanation. My question is what is the sense of currying if JS can take multiple arguments already? In what real-life applications or use of currying? Is the use of the partial application the most common way we use currying?
@@DaveGrayTeachesCode Thank you, I kinda get it now. No wonder, you mentioned the function composition. Does it mean, it is more for the readability of the functions, looks like more of following the DRY principle?
Hey dave it was hard for me to understant the last example ,especially when u did implement bind to create a new function curried and why u did put null in the first argument ,and what curried function also was used for in that case,it's a little bit complicated if u could please help me out with that
This is a nice but a bit complicated topic, after getting some understanding on the various ways of creating a function, the hard part now is to remember the names of all these concepts🤯😵 one use case for currying could be 2 factor authentication, approval of some kind of documents where the hierarchy of signing the document is required, I think 🤔 Thanks Dave, you look so hungry today, I mean awesome 😁
You are correct, my friend! And yes, that might be a good application for currying using composition. I plan to cover a bit more on functional composition soon. Thanks for the comment! 💯🙏
Hello, sir! I have one question. In “curry” example, I’ve wrote code as same as yours, but in console, I have error: “Uncaught ReferenceError: curried is not defined”. When I rewrote the code the following way: const curry = (fn) => { return function curried(...args) { if (fn.length !== args.length) { return curried.bind(null, ...args); } return fn(...args); } } the error is disappear. Why the code you had wrote is working properly? Thanks you in advanced! P. S. I've understood that using strict mode, and that was a problem.
At the time I made this video last year, I was using Bracket Pair Colorizer 2. It is now deprecated because VS Code added this functionality without the need of an extension. There are directions for how to enable native bracket matching in VS Code on the extension page (which was very nice of the developer!): marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer-2
Possibly. I made this video last summer. One thing I like about programming is there is usually more than one way to arrive at a result. The examples here are for showing how currying works, but I am sure they are not the only way to reach that result.
@@DaveGrayTeachesCode that's awesome. Most of the time my projects consist of a handful of files using modular classless OOP but it looks a bit messy. I've been looking for videos on this, inspiring repos...Can you help? :)
We can do this to do for variable length args for curry function: const curry = (fn) => { let curriedFunc; let len = 0; return curriedFunc = (...args) => { if(args.length === len) return fn(...args); len = args.length; return curriedFunc.bind(null, ...args); } }; const total = (...args) => args.reduce((prev, curr) => prev + curr, 0); const sum = curry(total); console.log(sum(1)(2)(3)()); Output: 6 So the big idea is that build the args list from args.length === 0 till the args.length === m where m is the total number for which you the sum and once that list is generated add 'em up and for that we have the variable len = 0 as len
Could you please elaborate on what happens after 'return curried.bind(null, ...args)' gets executed? Is it being called again but with more arguments until it reaches args.length? I understand that a new function is created, but is it being called at the same time which triggers it to call itself? Sorry, but I'm kinda struggling with understanding the currying process.
Good question and no need to apologize! This is complex stuff! You are asking about the curry function at (13:00) that we can use to curry other functions. You are right about nearly everything except the part where you say "triggers it to call itself". Bind does create the new function, but it doesn't call itself. It is essentially already being called just like when we return any function as a decorator function. We're returning curried as the function that will be called on line 246. We're binding to curried so the new function gets called as one of the functions in the curry process. It's ok to take time to digest all of this. I know it is more complex than most! Again, good question! 💯
@@DaveGrayTeachesCode "We're binding to curried so the new function gets called as one of the functions in the curry process. " This cleared it up for me. Currying is a bit of a mind job, kinda like recursion, but it's starting to make more sense. Thanks for taking the time to explain it to me. I really appreciate it. Not sure if you're in the states, but if you are, I hope you have a Happy Thanksgiving!
Parameters are part of the point which also lets you create partials. Here's a great article that dives into it all, too: medium.com/javascript-scene/curry-and-function-composition-2c208d774983
Thanks a lot for making this wonderful video! I watched at least three times until I understand the basic concept. But I have a question, at 12:16, why completeOrder still has access to function processOrder and even calls that?
Notice both processOrder and addCustomer take in completeOrder as an argument. We have curried the "chain" of functions and you do so in the reverse order they will be called. Also, notice the return in both addCustomer and processOrder... they return a function call with arguments spread in. Notice the order of returned values in the console as well. I think if you experiment with this code, you will see what is happening. It is not easy to comprehend right away.
@@DaveGrayTeachesCode Thanks for your reply! I played around with your example code and I think I have a better understanding of the concept. As I understanding, when we set new value of completeOrder to processOrder(completeOrder), like in line 188, now the completeOrder is actually a function with argument (…args) returned from processOrder. And then we update the value of completeOrder by passing addCustomer(completeOrder), like in line 190, at the moment the function addCustomer gets called and return another function. After all previous steps, when we call completeOrder we also invoke addCustomer and processOrder functions (because of closure). Is my understanding correct?
@@aliciapeter562 I do not have a book recommendation for CSS although there may be a good one out there. For Javascript, I really like Eloquent Javascript. The 3rd edition is free here: eloquentjavascript.net/
I got lost at when the curry function started iterating through the arguments. What's the source behind the iteration? The ...args being passed are x, y, z at the time curried runs right? How does curry know that the arguments of the function are what's being passed as args?
At 11:45 you should see 3 functions. Both "addCustomer" and "processOrder" are curried to create partials. This means they receive a function represented as fn but they wont' complete until they receive the 2nd parameter represented as (...args). Below that, you'll see I build the order of the functions in the reverse order I want them to complete. This isn't easy to grasp at first. Take some time and play around with the code.
@@DaveGrayTeachesCode I think you're also recursing at 14:02 where curried is binding itself. What I don't get though is why we first pass one parameter then 2 then 3. Edit: I was looking at it all upside down. I was imagining the iteration happening while curry() was actually currying 'total' and not when curriedTotal was running. Thanks for the great video
Hello.Great video! Thankss. But I do not understand 7:23. I wrote the same thing but it does not work. Why idk ( Is this the same code like you.ve written? const updateElemText = id => content => document.querySelector(`#${id}`).textContent = content const updateHeaderText = updateElemText("header") updateHeaderText("Hello world")
Do you have an HTML element with the id equal to "header" ? You pass that id value to the updateElemText call first when we define updateHeaderText. At that point, updateElemText is a partial and that is what updateHeaderText is equal to. It does not complete until we pass the 2nd argument which is the content parameter. We pass that as "Hello world" when we call updateHeaderText.
Each time an argument is passed to the function call, args.length will increase. When it receives only 1 or 2 parameters, it is a partial. When it receives all 3, it will execute the function.
there's something not looking right on the customer order example. it's not why curry's definition tells us: Currying is a transformation of functions that translates a function from callable as f(a, b, c) into callable as f(a)(b)(c). it's more like a decorator like the author says.
Currying = a function that takes multiple arguments and puts them into a function that takes them one at a time. a function that takes multiple arguments and puts them into a function that takes them one at a time
Well, what is the purpose of all that except playing Curry games ? Everything you showed could be achieved in other simpler ways. I hope you understand I am blaming the overall trend not you personally. Thank you and greetings from Bulgaria. Updated : Once I wrote my question I saw similar one and the answer was "... It’s helpful when we have many places that use a function with exactly the same way. Our implementation will be shorter and more readable." Ughhhh ... well, OK.
Don't feel stupid. This is advanced stuff. Play around with it a little bit. Come back to it tomorrow. All good things come with a little time. You got this!
@@DaveGrayTeachesCode why do you need to reassign completeOrder = processOrder(completeOrder)? I tried let order = processOrder(completeOrder) instead of reassign to completeOrder, and it worked fine. And why do you need to parentheses like ( processOrder(completeOrder))? I think it works fine without it, too. And at completeOrder = (addCustomer(completeOrder)), it means (addCustomer(processOrder(completeOrder))? I'm sorry for many questions, but I watched 10times and can't figure out....I really want to understand this.
why just not call them higher order functions? As well, 3...2...1... till we see this pattern abused by novice programmers since they learned this "new" technique and start using willy-nilly making their code less readable. In other words, try to avoid this as much as possible. Use this ONLY when the code becomes more elegant than by solving the other way. Basically, those approaches should really be used to code business logic, processing order example is terrible for this case. Those techniques should only be used in service functions (logging, etc) or when creating a framework, or when implementing some other advanced patterns
At the time I was playing around with the color filtering for the image. Trying to get a better skin tone because I am pale but I guess I didn't pay attention to my teeth color tone! Oh well. That's a bit harsh but I will pay more attention next time.
Man, thank you for all these great tutorials , you hardly ever see some advanced topics like this on youtube, I really appreciate your efforts
You're very welcome!
Currying functions in Javascript is an advanced topic. Once you understand how to curry a function and how to use curried functions, it can be a very useful feature in your code. This tutorial will cover the what, why, and how to's of currying functions in Javascript. All this talk of currying really just makes me hungry! 😂 If you are just learning Javascript, you should start with my full 8 hour course tutorial here: ruclips.net/video/EfAl9bwzVZk/видео.html
Please make more videos about advanced topics and concepts in an easy, digestible way you do naturally. RUclips is filled with too many videos about basic stuff. You'll make a huge difference daring to be different from other youtubers. I enjoyed your explanations so much. Thanks.
Thank you, Matin! 🙏
So true! It's like the holy grail of the js youtube here!
I love that timeTen example, I've used currying before but other than to scope variables I didn't see much of a use case for it. The times 10 example really gives me a great reason for caring about it much more as it allows for possible cleaner reusable code. Great video Dave.
Thank you CG! 🙏💯
Thank you for making the content! I was confused by most of the JavaScript curry related contents, but this one really helped me understand well!
Glad I could help! 🙏💯🚀
I first learnt about the term 'curry' through a Leetcode Javascript qns. Even though curry function is a kind of higher order function, it is still quite hard for me to understand currying through a challenging question. Thanks so much for breaking down the concept of currying starting from a very simple example. I understand it a lot better now!
Thank you for this video. My head has been hurting all day trying to truly understand currying. I don't want to move on before I get the logic behind it. I'm not a 100% but I definitely felt some flashes of understanding while watching your video.
It’s hard for me to understand some concepts. But i understood all of what you had to say about currying. Now i understand currying better than other topics that are alot simpler. Thanks
Glad it was helpful!
You are awesome..you teach us more easyly and briefly..hope you make more advanced topic
Thank you! 🙏
man i don't know where you come from, you saved millions of wasting time
You're welcome! 🚀
Man, your video came to me in the exact time! I see for some days trying to understand a debounce function, and was about to ask in SO, but your video made me understand it. REALLY thanks.
Thank you so much! really helped me to understand the Haskell function types
My search ended here on complete understanding and the entire existence of curry functions.
Very well explained. Thanks for the video!!
You're welcome!
you are a awesome teacher
Thank you! 😃
Damn dude, I just love the way you teach things. And the knowledge you are giving out to people is just marvellous. A person learns this kind of stuff while working in the industry. Thanks to you for teaching us beginners how things really work.
You're welcome and thank you for the kind words!
@@DaveGrayTeachesCode Quick question, do you have any plans for teaching us about Rest Apis in the upcoming videos?
Man, this is really interesting. With the basic examples, it's like wtf for? But then you see it in action and... wow.
That's some great examples. Thank you for your explanation!
Dave, thank you very much for all your efforts! I watch your videos over and oveer and every time a new layer of konwledges reveals itself and make me go "WOW!"
Great to hear!
Crystal clear, amazing, thanks !
What a great class! thank you for teaching us with real-world usages of these concepts.
Hi Dave, thanks for making this video. I've seen a few vids on currying and I am still wondering is there a situation where currying would be preferred over regular function calls? Or is this really just a stylistic choice?
Great question, Kevin! It is useful when following a functional programming approach - but not necessary as JS does accept more than one parameter in a function (as opposed to Haskell). That said, here is a good quote on the practical application of currying followed by the link to the original source: "Currying is a type of partial function application. We can use its returned functions to make a lighter version of an existing function. It’s helpful when we have many places that use a function with exactly the same way. Our implementation will be shorter and more readable." huynvk.dev/blog/currying-in-javascript-and-its-practical-usage Thanks for asking! 💯🙏
Thank you so much!
Enlightening and much informative
You're welcome!
Hey Dave, thanks for your advanced javascript concepts course. You lay down them pretty easily. All of these examples do help a lot, thank you very much!)
You're welcome! 🙏
Loving your content & delivery Dave!! Pure gold. Keep up the great work.
Much appreciated!
I REALLY liked this! Very clear. Thank you so much Dave. I'm off to make curry and recursively walk backwards through my tree data. I may be some time.
Glad I could help!
I recently started reading O'Reily Books' Learning React. They touch on currying for like a paragraph. This video opens up such a better understanding!
I'm glad it helped! 💯
Really great video. I return to it for the second time aldready.
Thank you for the kind words, Yulius! 🙏
@@DaveGrayTeachesCode especially for the currying function. I sometimes use it in my projects.
Hey Dave ! Take a look at this problem :
We need to write a curried sum finction which can accept any "n" numbers of params and at the end returns the sum of all the params. The catch is that in the end it will receive undefined as a parameter so that it knows to return the sum now :
- sum(1)(2)(3)(); // should return 6
sum(1)(2)(); // should return 3
sum(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)() // you get the idea.
How can we write something like this ??
Thanks in advance !
I love all your videos, but it was best of all. Truly exciting. Thank you ⭐⭐⭐⭐⭐
Glad you enjoyed it!
Love the advanced content! Explained very succinctly
Glad you liked it!
Hi Dave, thank you very much. I wished I had found your channel sooner. I have had difficulty understanding this concept and I'm not even a beginner n JavaScript. Thank you very much. I've subscribed and gave the video a big like. I'm hoping to see more exciting and insightful videos.
Thank you, David. Glad I could help!
thanks a lot! great explanation! Cheers
Great Tutorial 🥰🥰
Best explanation. Thanks!
Glad it was helpful! 🚀🚀
Excellent content as always!
Thank you, Aman!
Thanks for this video. I've watched a few and this did the best job of explaining why this is so useful.
Glad to hear I helped! 🚀
beginner-friendly with easy to comprehend description. you're a genius!
Thank you! 🙏
Thanks very much, my curry turned out delicious
Glad to hear it! 🍛
Never disappoints ,amazing job Dave
Thank you, Ted! 🙏
Wonderful explanation about the concepts of currying, now this concept is totally clear to me, thank you very much @Dave, please keep creating nice videos.
Glad I could help and thank you for the kind words!
thanks for the video!
You're welcome! 🙏
Great video, looking forward to more JS content as I'm a big fan of functional programming. Btw nice t-shirt 😁
Thanks! 🙏💯
thanks bro, nice explaining
Welcome!
thanks SO much for the excellent content. I've been a web designer and IT person my whole life, but like a lot of 'web designers', JavaScript in the early days was hard, the books were daunting, and I of course am familiar with how to add it too my pages, get it working, and write the most basic stuff. but getting deeply into it, has never been a serious goal. but last year, I was forced to learn to maintain an application written in angular/typescript. so I learned it mostly. and that got me into trying to learn react. the more tutorials in react I started, I realized no. I need to obviously master the language first! so here I am! lol. your videos are really helping me to understand some of the more tricky aspects of JS. so, about currying functions... are these techniques used in modern frontend design very much? if I understood the video correctly, the parameters of the curried functions can be passed in separately. so does that mean at different times in the future? is this somehow related to async/await, or am I thinking about it wrong? I guess I am trying to understand where and how these are used. I guess I'll watch it again lol. thanks again for the amazing content!
You're welcome! When currying, you can create a partial - a function that has not received everything it needs yet. That is different than async / await which I cover in detail here: ruclips.net/video/VmQ6dHvnKIM/видео.html
hey dev what is use of null in this line return curried.bind(null, ...args)
Best teacher)
Thank you! 🙏
Currying is such an important concept but the only video I could find a generalized currying function implementation is yours. Thank you !
You're welcome! 🙏🚀
I think the key to understanding the curry function in this video is the part that uses bind: it creates a function that has part of the arguments "pre delivered".
Simple example: the 5 will be automatically put to the add function (add5 is "fixed' with 5):
const add = (x, y) => x + y;
const add5 = add.bind(null, 5);
console.log(add5(10)); // 15
Hope it helps someone, who like me, has rather imperative background and FP concepts are puzzling.
Great comment! 💯
Curry functions can be considered decorator functions and/or HOF (Higher Order Functions)?
Yes, but saying it is curried or is a curry function gives a more explicit meaning. We have many liquids for example, but saying something is water gives a more explicit meaning.
Great explanation.
Question.
In the last example, how come the function
const total = (x, y, z) => x + y + z
when passed as argument as curry(total) and when we get fn.length in curry definition, it gives 3?
Shouldn't it give 1 because we have passed function "total" entirely as an arg to "curry" and not (x, y, z)
Thanks in advance.
thank you . i liked the way you teach lot. clear , wise and lot of knowledge! for instance you log ' [...args].toString() and. `[args[0]` . these are little things but demonstrate teaching effort of you
Thank you, Matt 🙏
Hi, thank you for your great explanation. My question is what is the sense of currying if JS can take multiple arguments already? In what real-life applications or use of currying? Is the use of the partial application the most common way we use currying?
Good article on this topic: medium.com/dailyjs/why-the-fudge-should-i-use-currying-84e4000c8743
@@DaveGrayTeachesCode Thank you for your quick reply. Your videos are great! Subscribed already.
@@DaveGrayTeachesCode Thank you, I kinda get it now. No wonder, you mentioned the function composition. Does it mean, it is more for the readability of the functions, looks like more of following the DRY principle?
Hey dave it was hard for me to understant the last example ,especially when u did implement bind to create a new function curried and why u did put null in the first argument ,and what curried function also was used for in that case,it's a little bit complicated if u could please help me out with that
This is a nice but a bit complicated topic,
after getting some understanding on the various ways of creating a function, the hard part now is to remember the names of all these concepts🤯😵
one use case for currying could be 2 factor authentication, approval of some kind of documents where the hierarchy of signing the document is required, I think 🤔
Thanks Dave, you look so hungry today, I mean awesome 😁
You are correct, my friend! And yes, that might be a good application for currying using composition. I plan to cover a bit more on functional composition soon. Thanks for the comment! 💯🙏
@@DaveGrayTeachesCode I wish I can support you more but things are going crazy where I am
Regards
@@ahmad-murerythank you 🙏 Hang in there!
Thank you so much, this is an interesting concept but I don’t think it is readable
Hello, sir! I have one question. In “curry” example, I’ve wrote code as same as yours, but in console, I have error: “Uncaught ReferenceError: curried is not defined”.
When I rewrote the code the following way:
const curry = (fn) => {
return function curried(...args) {
if (fn.length !== args.length) {
return curried.bind(null, ...args);
}
return fn(...args);
}
}
the error is disappear. Why the code you had wrote is working properly? Thanks you in advanced!
P. S. I've understood that using strict mode, and that was a problem.
what VS Code extension do you use? it uses different colors for different {}, this is awesome
At the time I made this video last year, I was using Bracket Pair Colorizer 2. It is now deprecated because VS Code added this functionality without the need of an extension. There are directions for how to enable native bracket matching in VS Code on the extension page (which was very nice of the developer!): marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer-2
Is it just me or most intermediate programmers feels dazed & confused while learning this topic?
It can take awhile to fully comprehend the more advanced topics. No worries. Take your time. You've got this! 💯🚀
Hi, isn't it simpler and cleaner (for the order example) to just use a builder function?
Possibly. I made this video last summer. One thing I like about programming is there is usually more than one way to arrive at a result. The examples here are for showing how currying works, but I am sure they are not the only way to reach that result.
Great content as usual. Maybe I'm being picky but you can hear some room echo, if you could upgrade your mic, golden...
You're right. I have since changed rooms and audio treatments. Big difference!
@@DaveGrayTeachesCode that's awesome. Most of the time my projects consist of a handful of files using modular classless OOP but it looks a bit messy. I've been looking for videos on this, inspiring repos...Can you help? :)
@@neithanm nothing specific comes to mind to share. You might search for file organization patterns. There are lots of approaches.
You are just awesome
Thank you!
We can do this to do for variable length args for curry function:
const curry = (fn) => {
let curriedFunc;
let len = 0;
return curriedFunc = (...args) => {
if(args.length === len) return fn(...args);
len = args.length;
return curriedFunc.bind(null, ...args);
}
};
const total = (...args) => args.reduce((prev, curr) => prev + curr, 0);
const sum = curry(total);
console.log(sum(1)(2)(3)());
Output: 6
So the big idea is that build the args list from args.length === 0 till the args.length === m where m is the total number for which you the sum and once that list is generated add 'em up and for that we have the variable len = 0 as len
Could you please elaborate on what happens after 'return curried.bind(null, ...args)' gets executed? Is it being called again but with more arguments until it reaches args.length? I understand that a new function is created, but is it being called at the same time which triggers it to call itself? Sorry, but I'm kinda struggling with understanding the currying process.
Good question and no need to apologize! This is complex stuff! You are asking about the curry function at (13:00) that we can use to curry other functions. You are right about nearly everything except the part where you say "triggers it to call itself". Bind does create the new function, but it doesn't call itself. It is essentially already being called just like when we return any function as a decorator function. We're returning curried as the function that will be called on line 246. We're binding to curried so the new function gets called as one of the functions in the curry process. It's ok to take time to digest all of this. I know it is more complex than most! Again, good question! 💯
@@DaveGrayTeachesCode "We're binding to curried so the new function gets called as one of the functions in the curry process. " This cleared it up for me. Currying is a bit of a mind job, kinda like recursion, but it's starting to make more sense. Thanks for taking the time to explain it to me. I really appreciate it. Not sure if you're in the states, but if you are, I hope you have a Happy Thanksgiving!
@@HologramJay thank you! And glad I could help!
One question is whether it is really necessary to have one parameter while writing a currying function.
Parameters are part of the point which also lets you create partials. Here's a great article that dives into it all, too: medium.com/javascript-scene/curry-and-function-composition-2c208d774983
Thanks a lot for making this wonderful video! I watched at least three times until I understand the basic concept.
But I have a question, at 12:16, why completeOrder still has access to function processOrder and even calls that?
Notice both processOrder and addCustomer take in completeOrder as an argument. We have curried the "chain" of functions and you do so in the reverse order they will be called. Also, notice the return in both addCustomer and processOrder... they return a function call with arguments spread in. Notice the order of returned values in the console as well. I think if you experiment with this code, you will see what is happening. It is not easy to comprehend right away.
@@DaveGrayTeachesCode
Thanks for your reply!
I played around with your example code and I think I have a better understanding of the concept.
As I understanding, when we set new value of completeOrder to processOrder(completeOrder), like in line 188, now the completeOrder is actually a function with argument (…args) returned from processOrder. And then we update the value of completeOrder by passing addCustomer(completeOrder), like in line 190, at the moment the function addCustomer gets called and return another function. After all previous steps, when we call completeOrder we also invoke addCustomer and processOrder functions (because of closure).
Is my understanding correct?
@@維倫劉 I think you've got it! Good job!
I really appreciate your time and excellent clarification!
Curry wasn’t too hard but the function that makes curry functions was 🤯
True! It really makes you think. 🚀
thanks
you are just as awesome as Greta Van Fleet in this tutorial. Thanks man 🤘
Ha! Thank you 🙏 I'm glad it helped! 💯🚀
thank you from Russia:)
You're welcome! 💯
Which vscode extension your using
Been awhile since this video so not sure what it was then, but right now I use the Github theme extension.
@@DaveGrayTeachesCode currently I am seeing highlight the curly braces
Perfect 👌
Thank you! 🙏
@@DaveGrayTeachesCode Hi Dave , I what book will you recommend for JavaScript & CSS , or What textbook is used in school . Thank looot .
@@aliciapeter562 I do not have a book recommendation for CSS although there may be a good one out there. For Javascript, I really like Eloquent Javascript. The 3rd edition is free here: eloquentjavascript.net/
@@DaveGrayTeachesCode Thank you
I got lost at when the curry function started iterating through the arguments. What's the source behind the iteration? The ...args being passed are x, y, z at the time curried runs right? How does curry know that the arguments of the function are what's being passed as args?
At 11:45 you should see 3 functions. Both "addCustomer" and "processOrder" are curried to create partials. This means they receive a function represented as fn but they wont' complete until they receive the 2nd parameter represented as (...args). Below that, you'll see I build the order of the functions in the reverse order I want them to complete. This isn't easy to grasp at first. Take some time and play around with the code.
@@DaveGrayTeachesCode I think you're also recursing at 14:02 where curried is binding itself. What I don't get though is why we first pass one parameter then 2 then 3.
Edit: I was looking at it all upside down. I was imagining the iteration happening while curry() was actually currying 'total' and not when curriedTotal was running. Thanks for the great video
Hello.Great video! Thankss. But I do not understand 7:23. I wrote the same thing but it does not work. Why idk (
Is this the same code like you.ve written?
const updateElemText = id => content => document.querySelector(`#${id}`).textContent = content
const updateHeaderText = updateElemText("header")
updateHeaderText("Hello world")
Do you have an HTML element with the id equal to "header" ? You pass that id value to the updateElemText call first when we define updateHeaderText. At that point, updateElemText is a partial and that is what updateHeaderText is equal to. It does not complete until we pass the 2nd argument which is the content parameter. We pass that as "Hello world" when we call updateHeaderText.
I confused that why the args.length increases. 17:20
Each time an argument is passed to the function call, args.length will increase. When it receives only 1 or 2 parameters, it is a partial. When it receives all 3, it will execute the function.
there's something not looking right on the customer order example. it's not why curry's definition tells us: Currying is a transformation of functions that translates a function from callable as f(a, b, c) into callable as f(a)(b)(c). it's more like a decorator like the author says.
Currying = a function that takes multiple arguments and puts them into a function that takes them one at a time. a function that takes multiple arguments and puts them into a function that takes them one at a time
why would anyone write code in this way ?
Wawoooo 😁
I found that last concepts were too tricky.
Simply I wanna touch ur feet, sir. You made the concept very easy.
Thank you for the kind words!
anyone that read clean code has nightmares ooking at this. just because its there dont mean you have to use it. like having a weapon.
Well, what is the purpose of all that except playing Curry games ?
Everything you showed could be achieved in other simpler ways.
I hope you understand I am blaming the overall trend not you personally.
Thank you and greetings from Bulgaria.
Updated : Once I wrote my question I saw similar one and the answer was "... It’s helpful when we have many places that use a function with exactly the same way. Our implementation will be shorter and more readable."
Ughhhh ... well, OK.
I know classic JS but this makes 0 sense to me tbh. I feel stupid
No need to feel bad. This is advanced JS. Take it slow. A little progress every day 💯
I watched at least 4times but still can't follow from 7:39....feel stupid.
Don't feel stupid. This is advanced stuff. Play around with it a little bit. Come back to it tomorrow. All good things come with a little time. You got this!
@@DaveGrayTeachesCode why do you need to reassign completeOrder = processOrder(completeOrder)?
I tried let order = processOrder(completeOrder) instead of reassign to completeOrder, and it worked fine. And why do you need to parentheses like ( processOrder(completeOrder))? I think it works fine without it, too. And at completeOrder = (addCustomer(completeOrder)), it means (addCustomer(processOrder(completeOrder))? I'm sorry for many questions, but I watched 10times and can't figure out....I really want to understand this.
why just not call them higher order functions?
As well, 3...2...1... till we see this pattern abused by novice programmers since they learned this "new" technique and start using willy-nilly making their code less readable.
In other words, try to avoid this as much as possible. Use this ONLY when the code becomes more elegant than by solving the other way.
Basically, those approaches should really be used to code business logic, processing order example is terrible for this case.
Those techniques should only be used in service functions (logging, etc) or when creating a framework, or when implementing some other advanced patterns
Wtf did I just watch
Dave, bro, brush your teeth. Maybe invest in some whitening strips or sumn.
At the time I was playing around with the color filtering for the image. Trying to get a better skin tone because I am pale but I guess I didn't pay attention to my teeth color tone! Oh well. That's a bit harsh but I will pay more attention next time.
@@DaveGrayTeachesCode I figured it was the filtering based on the colors in the background.
This is awesome! Clear and to the point explanation.. Thank you! :)
You're welcome! 💯🚀