Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities.

This article also participated in the “Digitalstar Project” to win a creative gift package and creative incentive money

Currie,

Rying, or Currying, is a technique that converts a function that takes multiple arguments into a function that takes a single argument (the first argument of the original function), and returns a new function that takes the remaining arguments and returns a result.

Here we provide a checkAge function to determine whether the user’s input age is greater than the baseline

example

function checkAge (age) {
    let min = 18
    return age >=  min
}
Copy the code

We define the value of min directly inside the function this way, which is hardcoding (hardcoding is the software development practice of embedding data directly into the source code of a program or other executable, as opposed to getting data from outside or generating it at run time)

This time there is evil product manager jumped out: Ang? We want something more flexible, something that users can make their own decisions. How can you make your own decisions?

With the promise of the evil product manager, our version 1.0 update, with its unrecognized pace

Upgrade 1.0:

function checkAge (min,age) {
    return age >=  min
}
Copy the code

This makes the function more flexible by turning the hard-coded function into a pure one, but it also has some complications, such as the following example

checkAge(18.22)
checkAge(18.23)
checkAge(22.22)
checkAge(22.10)
Copy the code

We need to use it multiple times, and when comparing the same reference value, we need to enter parameters multiple times, which makes me feel uncomfortable. So the question is, how do you do it?

Listening to my ocD call, the powerful upgrade 2.0 is coming with its code!

Update 2.0

function checkAge(min) {
    return function(age) {
        return age >=  min
    }
}
Copy the code

So for those examples, we can do the following

// The user base value is 18
let checkAge18 = checkAge(18)
checkAge18(22)
checkAge18(23)
// The user base value is 22
let checkAge22 = checkAge(22)
checkAge18(22)
checkAge18(10)
Copy the code

This is actually the Curryization of the function.

I feel, this many can not optimize a little ah?

With this new generation of code that I’m struggling with, the carrier arrow function, ites6, known as the epochal founder of front-end magices6“Interview questionses6Here he comes!

Rewrite using es6’s arrow functioncheckAge

let checkAge = min= > (age= > age >= min )
Copy the code

With this modification, we have solved the checkAge method in one line, which is a qualitative leap over the previous version of checkAge2.0. I would call ES6 the strongest

Recall an interview question (about arrow functions’ this’ and normal functions’ this’)

Q: Is the “this” of the arrow function determined when it is defined or referenced? What about ordinary functions to which this refers?

A: The arrow function’s this refers to the same context in which the arrow function is defined. For normal functions, this is determined when the function is called; For arrow functions, this is defined when the arrow function is defined and cannot be changed

What is the Currization of a function?

When we need to pass multiple arguments to a function, we can modify the function. We can call a function, pass only partial arguments, and have the function return a new function that takes the rest of the arguments and returns the rest of the results.

To sum up: In functional programming, function corrification refers to converting a function that takes multiple arguments into a higher-order function that takes an indefinite number of arguments. In terms of function, it has realized the refinement of function.

The application of Currification in Lodash

From the previous example, we understood the use of currization and currization, but the checkAge function is not universal, so how can it be universal?

Hearing our call, Lodash, the so-called Front End paramedic, stepped forward! But this time we’re going to use the curry function, the Lodash library is fine;

curryThis section describes the parameters and functions

  • Function:

    Creates a function that takes arguments to func, either calls the result returned by func, or returns the result executed by func if the required arguments are already provided. Or return a function that takes the remaining func arguments. You can use func. Length to force the number of arguments to be accumulated.

  • Parameters:

    1. func  (Function): the function used to curry.
    2. [arity=func.length]  (number): Needs to be providedfuncThe number of arguments.
  • Returns:

    (Function) : Returns the new curry Function.

curryuse

It turns out that a function of several variables can be converted into a function of one variable

const _ = require("lodash")
function sum(a, b, c) {
  return a + b + c;
};
 
const curried = _.curry(sum);
// It seems that there is no need to use this method
curried(1.2.3); / / = > 6
// Check this out
curried(1) (2) (3); / / = > 6
// Take a look at this
curried(1.2) (3); / / = > 6
Copy the code

When Curry is currified, it will return the parameters we passed in, and if we pass in two with three parameters, Curry will return a function that needs the remaining parameters. Slim look at the analysis below!

Here, will you find that the method of Cremation is very easy to use, but even if it is easy to use the wheel is made by others, it is not good to always use other people’s wheels, or we go on!

Simulation of the Currization principle

As we learned in the previous section, the parameters curry needs are fun and the number of parameters it needs to supply to func,

currySeveral forms of use of

function getSum (a,b,c) {
    return a + b + c
}
const curried = _.curry(getSum)
Copy the code

Let’s take a look at how this function Curried can be called, right

  1. Pass all parameters

    curried(1.2.3)
    Copy the code

    If the arguments we pass in match the arguments that getSum needs, we immediately call getSum and return the result

  2. Passing in some parameters

    curried(1.2) (3)
    curried(1) (2) (3)
    curried(1) (2.3)
    Copy the code

    If we pass in some arguments, at this point Curried returns a new function and waits for getSum to take the rest of the arguments

Through the above analysis, we return to the function, at the time of call need to accept parameters, but also to receive the number of parameters is not fixed, we need to get all the parameters, and we need to make a judgment, the number of parameters are the same, so with the above requirements, we simulate a formal implementation.

Code to simulate

  1. We need to be able to take a function and return a function
function curry(fun) {
    return function () {... }}Copy the code
  1. We need to return functions that can accept new arguments that we can passes6To obtain the remaining parameters
function curry(fun) {
    return function (. args) {... }}Copy the code
  1. We need to check whether the number of arguments and parameters are the same
  • Number of arguments:argsIt’s an array. We can useargs.lengthGets the number of arguments when we actually call this function.
  • The format of the parameter: is what we pass infunThe number of formal parameters of this function, we’re going to getfunThe number of parameters we can passfun.lengthTo obtain
  • If the argument < parameter then returns a new function that accepts the remaining parameter values
  • If the >= argument then fun is called directly, returning the execution result

Argument >= parameter

```js function curry(fun) { return function (... Args){if(args. Length < fun.length){return function() {... }} // the argument >= parameter returns fun(... args) } } ```Copy the code

Argument < parameter

With the < parameter, each time we call the function, we need to preserve the previous condition and pass it on to the next regenerate function each time

```js function curry(fun) { return function curriedFn(... Args) {// Check the number of arguments and parameters // argument < parameter then return a new function, If (args.length < fun.length){return function() {// arguments is array. from return curriedFn(... Args. Concat (array. from(arguments)))}} return fun(... args) } } ```Copy the code

So that’s where we’re done with Curry.

conclusion

  • Corrification allows us to pass in fewer arguments to a function and get a new function that has memorized some of the fixed arguments
  • This is a cache of function parameters
  • Make functions more flexible and smaller in granularity
  • You can convert multivariate functions into unary functions, and you can combine functions to produce powerful functions

We used checkAge to demonstrate the use of Curryization, but it is not general, so we introduced the Method of Curryization in Lodash, and according to it, we also simulated the implementation of curry function.