Author: CAI Xuguang

An interview question

We have an Add method.

function add(a, b, c) {  
  return a + b + c;
}
add(1.2.3)   / / 6
Copy the code

Implement a sum method that satisfies the following conditions:

sum(1) (2.3)   / / 6
sum(1) (2) (3)   / / 6
Copy the code

In fact, this problem uses the idea of function Currization, and we can convert the add method into the sum method by means of function Currization.

So let’s see what a function corrification is.

What is the Currization of a function

Wikipedia defines currification as follows:

In computer science, Currying, also translated as carryization or callization, is a technique of converting a function that takes multiple arguments into a function that takes a single argument (the first argument of the original function), and returning a new function that takes the remaining arguments and returns a result.

In plain English: Call a function with just a few arguments and let it return a new function to handle the rest.

Here’s an example of understanding Currization:

Let’s say you have a store, and it’s on sale, and you want to give regular customers a 10% discount on everything.

function setDiscount(price, discount) {  
    return price * discount;
}
Copy the code

When an ordinary customer buys a commodity that costs 100 yuan, you can calculate the price:

const price = setDiscount(100.0.9);
Copy the code

You will find that every time you calculate the price of an item, you need to enter the price and discount, which is very troublesome.

const price1 = setDiscount(500.0.9);
const price2 = setDiscount(1000.0.9);
const price3 = setDiscount(2000.0.9);
Copy the code

We can corrize the function setDiscount to avoid entering discount every time.

function currySetDiscount(discount) {  
    return function(price) {    
        return discount * price;  
    };
}

const setNinetyPercent = currySetDiscount(0.9);
Copy the code

Now we can calculate the price of goods for the average customer:

const price = setNinetyPercent(500);
Copy the code

Similarly, for VIP customers, there is a 20% discount for all products, which can be calculated as follows:

const setEightyPercent = currySetDiscount(0.8);

const price = setEightyPercent(500);
Copy the code

This function can be understood as parameter reuse, delay execution, reduce code redundancy, increase code readability.

Simple implementation of currization of functions

Going back to the original problem, let’s write a Curry function.

function curry(fn, args) {  
    let len = fn.length;  // The parameter length of the function to be currified
    let tempArgs = args || [];  
    return function() {    
        tempArgs = tempArgs.concat([...arguments])    
        if (tempArgs.length < len) {      
            return curry.call(this, fn, tempArgs);    
        } else {      
            return fn.apply(this, tempArgs); }}; }Copy the code

The function is executed when the number of arguments is the same as that of the original function.

Add can be currified like this to generate the sum method:

var sum = curry(add);

sum(1) (2.3)   / / 6
sum(1) (2) (3)   / / 6
Copy the code

Application of currization of functions

Delay calculation

The bind function we use all the time.

let obj = {
  name: 'jack'
}
let showName = function() {
    console.log(this.name)
}
let showJackName = showName.bind(obj);

showJackName(); // jack
Copy the code

Here bind is used to change the context in which the function is executed, but the function itself is not executed, so it essentially delays the calculation.

If we look at the mock implementation of BIND, it’s essentially a currization.

function myBind(){
  var self = this;
  // The first object argument
  var context = Array.prototype.shift.call(arguments);
  // Other parameters
  var bindArgs = Array.prototype.slice.call(arguments);
  // temporary functions
  var fTemp = function(){};
  function fn(){
    // Merge binding parameters and call-time parameters
    var args = bindArgs.concat(Array.prototype.slice.call(arguments));
    // Execute the original function (this refers to the given object)
    self.apply(context, args);
  }
  // temporary function prototype refers to the original function prototype
  fTemp.prototype = self.prototype;
  // New function prototype set to temporary function instance object (when the original function uses New to create instance object)
  fn.prototype = new fTemp();
  return fn;
}
Copy the code

conclusion

Function currification is one of the most basic operations in functional programming (a programming paradigm). It is derived from and mainly serves functional programming (the combination of functions requires a single parameter function). We don’t really need to differentiate between functions in our daily development. Closures, higher-order functions, and so on are all similar to functions to some extent.

For more shared articles from skFeTeam, click herehere, thank you ~