21

Recently I read about function composition in a Javascript book, and then on a website I saw someone reference it as currying.

Are they the same concept?

omarjmh
  • 13,632
  • 6
  • 34
  • 42
Dino Liu
  • 500
  • 4
  • 17
  • 3
    they are related concepts, but not exactly the same. to compose is to make two into one, to curry is to pre-define part of one. – dandavis Mar 29 '16 at 01:44
  • @dandavis can you maybe post an answer outlining the differences? Can they be used to achieve the same goal? – Aaron Gillion Mar 29 '16 at 01:49
  • it's been explained well already in enough places that i would fail to do it justice. but in short: they are not the same, so study each one and figure out what each one means and does, to figure out how they apply to each other, if they do. – dandavis Mar 29 '16 at 01:52
  • 1
    Not quite the same: [What is Currying](http://stackoverflow.com/questions/36314/what-is-currying) and then separately [Function composition in Javascript](http://stackoverflow.com/questions/28821765/function-composition-in-javascript). Currying is typically prewiring certain function arguments into a new function that isn't passed those arguments. Function composition is how you combine multiple existing functions to create a new function that carries out some combination of the other's function by calling some `compose()` function, not just handwriting a new function. – jfriend00 Mar 29 '16 at 01:59
  • You have to provide more information to get a proper answer. –  Mar 29 '16 at 08:19

2 Answers2

30

@Omarjmh's answer is good but the compose example is overwhelmingly complex for a learner, in my opinion

Are they the same concept?

No.

First, currying is translating a function that takes multiple arguments into a sequence of functions, each accepting one argument.

// not curried
const add = (x,y) => x + y;
add(2,3); // => 5

// curried
const add = x => y => x + y;
add(2)(3); // => 5

Notice the distinct way in which a curried function is applied, one argument at a time.


Second, function composition is the combination of two functions into one, that when applied, returns the result of the chained functions.

const compose = f => g => x => f(g(x));

compose (x => x * 4) (x => x + 3) (2);
// (2 + 3) * 4
// => 20

The two concepts are closely related as they play well with one another. Generic function composition works with unary functions (functions that take one argument) and curried functions also only accept one argument (per application).

// curried add function
const add = x => y => y + x;

// curried multiplication function
const mult = x => y => y * x;

// create a composition
// notice we only apply 2 of comp's 3 parameters
// notice we only apply 1 of mult's 2 parameters
// notice we only apply 1 of add's 2 parameters
let add10ThenMultiplyBy3 = compose (mult(3)) (add(10));

// apply the composition to 4
add10ThenMultiplyBy3(4); //=> 42

// apply the composition to 5
add10ThenMultiplyBy3(5); //=> 45 
Mulan
  • 129,518
  • 31
  • 228
  • 259
2

Composition and currying are used to create functions. Composition and currying differ in the way they create new functions (by applying args vs chaining).

Compose:

Compose should return a function that is the composition of a list of functions of arbitrary length. Each function is called on the return value of the function that follows. You can think of compose as moving right to left through its arguments.

Example:

var compose = function(funcs) {
  funcs = Array.prototype.slice.call(arguments, 0);
  return function(arg) {
    return funcs.reduceRight(function (a, b) {
      a = a === null ? a = b(arg) : a = b(a);
      return a;
    }, null);
  };
};


var sayHi = function(name){ return 'hi: ' + name;};
var makeLouder = function(statement) { return statement.toUpperCase() + '!';};

var hello = compose(sayHi, makeLouder);
l(hello('Johhny')); //=> 'hi: JOHNNY!'

Currying:

Currying is a way of constructing functions that allows partial application of a function’s arguments.

Example:

var addOne = add(1);
var addTwo = add(2);

var addOneToFive = addOne(5);
var addTwoToFive = addTwo(5);

l(addOneToFive); //6
l(addTwoToFive); //7

JSBin with the above examples: https://jsbin.com/jibuje/edit?js,console

omarjmh
  • 13,632
  • 6
  • 34
  • 42