Jefferson DanielNavigate back to the homepage

using currying in javascript

Jefferson Daniel
December 21st, 2017 · 3 min read

Index

  1. Introduction
  2. History
  3. Currying vs partial application
  4. Partial Application
  5. Currying
  6. Who use
  7. Real world examples
  8. Conclusion

Introduction

This post is a study about currying, and about partial application too that for my in the beginning of studies are the same thing, this concept is a native feature in a lot of functional program language, this isn’t native in javascript but is possible implement and use this technique similarly.

History

The currying technique takes this name because the mathematician North American Haskell Curry, yes the same honoured for the Haskell program language, Curry Haskell develop the concept of currying of the combinatory logic, created by Moses Schönfinkel.

“The technique of translating the evaluation of a function that take multiple arguments into evaluating a sequence of functions, each with a single argument” - Wikipédia

Currying vs Partial Application

The currying is the process to transform a function that takes multiple parameters to one chain of functions, currying always works with with unary functions, that is, each one function not take more of one argument. However the Partial Application is when we have functions with more arguments, and after execute then she will returns other function with less arguments.

Partial Application

We can get as example a sum function, that in your definition receive two parameters, using this concept, when this function is called she can receive: the two parameters and everything happens normally as usual, or she can receive just one of the parameters, in this case she will returns a other function that will receive the missing parameter, see the implementation of this function in example bellow:

1var sum = function( x, y ) {
2 if( typeof y === 'undefined' ) {
3 return function ( y ) {
4 return x + y
5 }
6 }
7
8 return x + y
9}

Understanding how this technique works, we can use the ES6 and a ternary condition to transform this in something less verbose. We can return the sum function to a constant, use arrow functions without keys already that she always will returns something, and use a ternary condition to verify if the second parameter was passed our nor.

1const sum = ( x, y ) =>
2 typeof y === 'undefined'
3 ? y => x + y
4 : x + y

After this you can call this sum function with more flexibility, passing the two parameters in the same time, or applying she partially.

1sum(5,5) // 10
2sum(5)(5) // 10
3
4var result = sum(5) // y => x + y
5result(5) // 10

Currying

In example below we have a function with name curry, she receive three parameters fn, x and y, in this case fn is a function that receive x and y as parameters, but how usually is, fn not receive all parameters in one single time, he receive the first parameter, execute and return a new function to receive the next parameter, and at the end is executed the function with all that she needs f(x,y).

1function curry(fn) {
2 return function(x) {
3 return function(y) {
4 return fn(x, y);
5 }
6 }
7}
8
9function sum(x,y) {
10 return x + y
11}
12
13const result = curry(sum)(5)(5) // 10

In the same way that we made in Partial Application we can write it with fewer lines.

1const curry = f => x => y => f(x, y)
2const sum = (x,y) => x + y
3
4const result = curry(sum)(5)(5) //10

In this case the function curry that was created can be reused in other operations in the same way that was used in sum example, with this we can pass our parameters separately.

1const curry = f => x => y => f(x, y)
2const sum = (x,y) => x + y
3const subtraction = (x,y) => x - y
4const multiply = (x,y) => x * y
5
6const result1 = curry(sum)(5)(5) //10
7const result2 = curry(subtraction)(5)(5) //0
8const result3 = curry(multiply)(5)(5) //25
9
10const curried = curry(sum)
11curried(5)(5) //10

Who use?

The Rambda for example that is a javascript function library, use Partial Application in many functions, where the functions wait your parameters but if you not pass all of the necessary, will be returned a new function and always gonna work as should, see some examples:

1R.add(2, 3); //=> 5
2R.add(2)(3); //=> 5
3
4R.replace(/foo/g, 'bar', 'foo foo foo'); // => "bar bar bar"
5R.replace(/foo/g, 'bar')('foo foo foo'); // => "bar bar bar"
6R.replace(/foo/g)('bar')('foo foo foo'); // => "bar bar bar"
7
8R.concat('bar', 'foo') //=> "barfoo"
9R.concat('bar')('foo') //=> "barfoo"
10
11R.equals("bar", "bar"); //=> true
12R.equals("bar")("bar"); //=> true

Please, give to me real world examples

Maybe just with the mathematical examples the I use above, get a little hard to take this to the reality, and you are thinking: cool, but I will really use this? maybe. One context where this can be apply, that is very common daily, is a request, probably you already see some lines of code looks like this sometimes:

1import axios from 'axios'
2
3const deleteData = id =>
4 axios.delete(`https://api.example.com/v1/${id}`)
5 .then(response => { ...response.data })
6 .catch(error => console.error(error))
7
8const searchData = id =>
9 axios.get(`https://api.example.com/v1/${id}`)
10 .then(response => { ...response.data })
11 .catch(error => console.error(error))
12
13// ...

Above we have a stretch of a CRUD, two requests, one method get and one delete in a REST API, we can receive as parameter beyond the id the method used by axios, so that in the first execution of function we can save a type of request, and after use this with different id’s.

1import axios from 'axios'
2
3const API = method => id =>
4 axios[method](`https://api.example.com/v1/users/${id}`)
5 .then(response => response.data)
6 .catch(error => console.error(error))
7
8
9const searchData = API('get')
10const deleteData = API('delete')
11// ...
12
13
14buscarDados('954') // => {...data}
15buscarDados('684') // => {...data}

Conclusion

the advantage that you can take of this concepts is the power of write function that wait receive many parameters, but have the control to apply then according to your need, or according you receive then, you can call your functions even if in current time your not have all required parameters yet. And is one more way to write generic functions for be used in different contexts.

Read more

More articles from Jefferson Daniel

taking more advantage of SASS

Exist some feature in SASS that is not very popular, but they can help us to save time when we are building our applications.

August 21st, 2016 · 3 min read

immediately invoked function expression

The IIFE or immediately-invoked function expression, is one of the ways to declare a javascript function, to understand better how a variable can receive a value of a IIFE before we need understand some concepts.

December 20th, 2015 · 2 min read
© 2015–2020 Jefferson Daniel
Link to $https://github.com/jeffersondanielssLink to $https://linkedin.com/in/jeffersondanielss