DEV Community

Discussion on: Currying in JavaScript

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️ • Edited

Nice article, but you seem to have a somewhat wrong idea of what currying is, and are conflating it with partial application. To clarify:

Partial application

A function is called with less arguments than it needs, and returns a new function that takes the remaining arguments. Some languages support this out of the box:

// Pseudocode. This doesn't work in real javascript.
const mul = (x, y) => x*y
const double = mul(2)
Enter fullscreen mode Exit fullscreen mode

And some, like JS, can only approximate this behaviour using higher-order functions:

const partial(fn, ...args) => (...rest) => fn(...args, ...rest)
const double = partial(mul, 2)
Enter fullscreen mode Exit fullscreen mode

Currying

On the other hand, currying is the process of taking any function and converting it into a series of nested functions of arity 1:

const mul = x => y => x*y
Enter fullscreen mode Exit fullscreen mode

This can sometimes be done automatically, but only in languages that offer some mechanism to inspect a functions arity, and generate a new (nested) function until the right number of arguments has been provided.

// Again, pseudocode. This doesn't actually work in JS.
const mul = curry( (x, y) => x*y)
const double = mul(2)
Enter fullscreen mode Exit fullscreen mode

Just for fun, here's an automatic currying function:

curry = fn => {
    let curried = (...args) => {
        if (args.length >= fn.length)
            return fn(...args)
        else
            return (...rest) => curried(...args, ...rest)
    }
    return curried
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
strubloid profile image
Strubloid

Just to be honest, I got scared of things like that:
const mul = x => y => x*y
This is something readable, but some people can enjoy this "non-hability" of creating variable names, that is the worse thing you can do, but the action of refactoring to become faster, I totally agree, but needs to be well written, and naming is important (even for a an internet example).

Collapse
 
linehammer profile image
linehammer

The practical answer is that currying makes creating anonymous functions much easier. Even with a minimal lambda syntax, it's something of a win; compare:

map (add 1) [1..10]
map (\ x -> add 1 x) [1..10]

If you have an ugly lambda syntax, it's even worse. (I'm looking at you, JavaScript, Scheme and Python.)

net-informations.com/js/iq/default...

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

I honestly don't think JS has such a bad lambda syntax; [1,2,3].map(x => 1+x) is still quite acceptable compared to what we have in Lua: function(x) return 1+x end*

* keep in mind that Lua is intentionally minimalistic, making it an easy transpilation target for languages with more convenient syntax, so this is effectively not a big problem

Collapse
 
kishorjoseph profile image
kishorjoseph • Edited

For your above definition of currying how can you say just one arity ? the last function can have any arity. Also, bellow matches to your definition of partial as well.

const add = a => (b, c) => a + b + c
add(1)(2,3)