Made my own curry function, I'd like some feedback

Hi!

I’m learning some more things about functional programming with JavaScript. Because currying is such a big thing in FP I was like “hey I wonder if I could make my own currying function” (to convert any function into a curried one). And I did!

But, I would like to have some feedback on it. Would you implement it differently? Do you think it’s clear enough? (given that it’s a somewhat complex mechanism).

(Edit: I know about the semicolons, for some types of code I just don’t like them.)
(Edit 2: I actually made an even shorter version, which I still think is kind of readable…)
(Edit 3: Ha, even smaller :smiley:)

Thanks!

Here’s the code (v1)

const curry = f =>
  curried = (...args) => {
    if (args.length >= f.length) {
      return f(...args)
    }
    let outerArgs = args;
    return (...innerArgs) => {
      return curried(...outerArgs, ...innerArgs)
    }
    // We get 0 arguments? Let's not do this one
  }

Here’s the code (v1) and some minor tests on Codepen.

Here’s v2:

const curry = f =>
  curried = (...args) => {
    let outerArgs = args
    return args.length >= f.length ?
      f(...args) :
      (...innerArgs) => curried(...outerArgs, ...innerArgs)
  }

I’m not too sure about line 2, where I set the name curried without using let/const/var.
JSHint did not complain and it also works… so… OK I guess?
And also: assigning something and then returning the result of the assignment statement always feels weird.
It is a lot shorter though…

The use of the ternary operator here is kinda nice I think.

v2 on Codepen:

v3:

const curry = f =>
  curried = (...args) =>
    args.length >= f.length
    ? f(...args)
    : (...restArgs) => curried(...args, ...restArgs)

This is getting ridiculous.

V3 on Codepen: https://codepen.io/niels_bom/pen/gBdLmO?editors=0011

1 Like

Pretty neat, the few tests I did seemed to work. You might want to add some type checking.

const curry = f => {
  if(typeof f != 'function') throw new TypeError('Expected a function');
  return curried = (...args) =>
    args.length >= f.length
    ? f(...args)
    : (...restArgs) => curried(...args, ...restArgs)
}

Unfortunately, I don’t think i can give you any really good feedback, I’m just not all that well versed in the functional paradigm.

1 Like