preface

Before, a friend of our group who has worked for 5 years came to the interview, and I was in charge of the written test of the interviewee because the team leader had something to do. There was a question in the written test: Implement an Add function and make add(2)(2)(3) return 7. I looked at the answer of the interviewee:

function add(a) {
    return function (b) {
      return function (c) {
        return a+b+c
      }
   }
}
add(2) (2) (3) / / 7
Copy the code

If I change the way I pass the parameters, I want you to write a function add(2,2)(3) that returns 7. Would it be written like this again?

function add(a, b) {
    return function (c) {
      return a+b+c
   }
}
Copy the code

Student: Do I have to write two different add functions if I change the way I pass arguments? Of course, if I were the interviewer, I would prefer you to write a more general add function, and I would prefer the interviewer to implement a curry function and then encapsulate the Add function.

Implement the Curry (Curryization) function

In fact, we look at the interviews of students writing code is already gave us a roughly write 🧭 curry function of direction, now that is a multiple parameters, whether the number of parameters that as long as we reach we need the number of parameters of the function, if did not meet our recursive get behind the incoming parameters, number until you reach the required parameters we can.

So let’s just write a Currie function.

function curry(func, args) {
  // Indicates the number of parameters required
  let funcLen = func.length;
  let argsTemp = args || [];
 
  return function() {
    // Since the argument is a class array and not a real array, we need to convert it here
    let _args = [].slice.call(arguments);
    _args = [...argsTemp, ..._args]

    // If the number of parameters is not enough, you need to recursively collect the parameters
    if (_args.length < funcLen) {
      return curry.call(this, func, _args);
    }
    // The func function is executed when the collection is complete
    return func.apply(this, _args); }}Copy the code

Call the curry function:

var add = curry(function(a,b,c){
    return a+b+c
})
add(2) (2) (3) / / 7
add(2.2) (3) / / 7
Copy the code

This completes the generic add function.

If the above questions you have implemented a curry function, I think will be more make the interviewer shine at the moment, sometimes interviewers ask most of the questions you must be in a variety of web sites will have the answer, than to recite the answer, the interviewer would be more hope you can dig or extension to talk about, answer any questions are one thousand readers, one thousand Hamlet, There will never be a single answer.

In fact, I have instilled a wrong definition when I write here. The following is the correct understanding:

  • add(2)(2)(3)Is a real sense ofCurrie,
  • Add (2, 2) (3)It’s actually aPartial Function Application

The difference between currization and partial functions

So what’s the difference?

Currization is a technique for converting a function that takes multiple arguments into a series of functions that take one argument.

Partial function application is to fix some parameters of a function and then produce another function with smaller elements.

The effect of cremation

Here’s an example of how this works:

// a function that makes a request
function ajax(type, url, params){... }// 1
ajax('GET'.'www.a.com'.123)
ajax('GET'.'www.a.com'.789)
ajax('GET'.'www.b.com'.456)

// 2
var get = ajax('GET')
var getAUrl = get('www.a.com')
var getBUrl = get('www.b.com')
getAUrl(123)
getAUrl(789)
getBUrl(456)
Copy the code

1. In the first way, ajax functions are called to make use of the versatility of Ajax functions, but the parameter transmission is still redundant.

2. Method two does not make use of the versatility of ajax functions, but disassembles them into pieces, so that parameters can be reused, which reduces the versatility but improves the applicability of functions.

Function combination compose

Now that we’re talking about Currization, can we not talk about combinations of functions? Functional combination, after all, is the other of the two masters of functional programming.

Function composition is simply a combination of functions, such as

var compose = function(f,g) {
  return function(x) {
    return f(g(x));
  };
};
Copy the code

The order of execution of this function is g(x)->f(x), right to left.

// Associative
compose(f, compose(g, h)) == compose(compose(f, g), h);
Copy the code

Implement a compose

function compose(. func) {
  return function(. args) {
    return func.reduceRight((acc, cur) = > {
      return typeof acc === 'function'? cur(acc(... args)) : cur(acc) }) } }// Use ES6
const compose = (. func) = > (. args) = > func.reduceRight((acc, cur) = > typeof acc === 'function'? cur(acc(... args)) : cur(acc))Copy the code

Testing:

const x = x= > x+1;
const y = x= > x*2;
const z = x= > x-2;

const c = compose(x, y, z);
c(2) / / 1
Copy the code

The execution sequence is Z -> Y -> X

The benefits of function composition

So what’s the advantage of using a combination of functions?

We now want to reverse an array of strings, uppercase them all, and output a string.

Conventional imperative programming is written:

log(toString(toUpperCase(reverse(arr))))
Copy the code

It does meet our requirements, but this infinite nesting is really unreadable and ugly.

Write the combination of functions:

compose(log, toString, toUpperCase, reverse)
Copy the code

We use the way we write function combinations, so we can see what order we call, and we can do all kinds of combinations.

As long as we abstract some complex functions into pure functions one by one, and combine them arbitrarily in different scenes, just like Tetris, although there are only several shapes, they can be put together to build a variety of different shapes.

conclusion

Today we are actually through a pen test led to a functional programming in the two important theory (functional combination and Currization), because of the theory of functional programming is more, I recommend this article (concise JavaScript functional programming – introduction) to understand the concept of functional programming.

Reference:

Simple JavaScript Functional Programming – Getting started Functional programming refers to the north JavaScript topic function Currization