loading...

Explaining currying to myself

Damien Cosset on September 18, 2017

Introduction Well, time to teach myself something I don't understand again... In this article, we will explore a technique called curryi... [Read Full]
markdown guide
 

Great article, Damien! There are just a few things I noticed in the definition of the curried function.
return fn( ...args ) should be return func( ...args ), I think.
Also, I don't quite get why you're defining nextFunc as an argument to the curried function. Is it just to declare the variable so that you wouldn't have to explicitly declare it inside the arrow function body and leave out the brackets? Just a bit unclear to me.

 

Oh, you are right, it should be func and not fn. Thank you, I updated the code.

You know what, I actually have an issue with that. If I remove nextFunc from the arguments, I have an TypeError when I call my curried function.

But, when I implement my same curried function using the function keyword :

function curried(func,arity = func.length) {
  return (function nextCurried(prevArgs){
    return function curried(nextArg){
      let args = prevArgs.concat( [nextArg] );

      if (args.length >= arity) {
        return func( ...args );
      }
      else {
        return nextCurried( args );
      }
    };
  })( [] )
}

I don't need to specify this third argument. My guess is ( and it's only a guess so far ) that the arrow functions somehow changes something in my implementation. I'll dig a bit more. Good question!

 

And don't forget to also change the default value of arity from fn.length to func.length :)

 

You can also do currying directly without having a curry-fier.

For example...

const cf = (a) => (b) => (c) => (d) => { return a + b * c - d; }

One of the things that I like about "functional-first" functional programming languages is that currying is the norm (as is immutability, concise syntax, pattern matching, non-nullable references, tail recursion, emphasis on purity), and you'd have to go out of your way to not do currying. For example, in F#:

let cf a b c d = a + b * c - d

That function is curried. And partial application is equally easy and straightforward:

let pa x y = cf 10 20

 

It does take more discipline to use the functional side of Javascript. I think I added a curry-fier because I wanted to play around with the number of arguments. But it does make it less readable.

 

The curried function with all its parens looks a bit too codegolf-ish :D I think there are opportunities to make it clearer.

But overall, great article!

code of conduct - report abuse