Learn about the JavaScript functional programming directory

  • 0- Understand JavaScript functional programming – What are pure functions
  • 1- Understand JavaScript functional programming – Currification
  • 2- Understand the benefits of JavaScript functional programming-code combinations
  • 3- Understand JavaScript functional programming – declarative functions
  • 4- Understand JavaScript functional programming – type signing

Code combination

Breeding code

Combinatorial functions look like building blocks. You are a child who can choose two blocks (functions) at random and splice them together to form a new toy (functions). Combinations can be used as follows:

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

F and g are functions, and x is the value “piped” between them. Note that the compose function is the most important part of the composite code idea, and is often used at 👇 below. You can mark it in advance

var toUpperCase = function(x) { return x.toUpperCase(); };
var exclaim = function(x) { return x + '! '; };
var shout = compose(exclaim, toUpperCase);

shout("send in the clowns");
//=> "SEND IN THE CLOWNS!"
Copy the code

So we’re going to combine the two functions and return a new function.

Contrastive combinatorial function

Think about it: What is the difference between a composed function and a full flow functionCopy the code
var shout = function(x){
  return exclaim(toUpperCase(x));
};
Copy the code

You can see that the combined functions are just like lego toys and can be freely combined into other complete models that are available. Lego models (full function functions), but a full function like the one above, cannot be detachable. It’s like a finished handyman.


  • It can’t be disassembled. It was designed when it came out of the factory.

Understanding composite code

Having code run from right to left, rather than inside out, is what I call “left”. Let’s look at an example where the order is important:

var curry = require("lodash").curry;
var reduce = curry(function(f, init, arr){
    return arr.reduce(f, init);
});

// Thank you for your suggestion (@thsing772). Here is a correction for reduce function. It should be curried before it can be used as follows:
var head = function(x) { return x[0]; };
var reverse = reduce(function(acc, x){ return[x].concat(acc); } []);You can also dispense with curry
// var reverse = x => x.reduce(function (arr,x){return [x].concat(ar)}[]);
var last = compose(head, reverse);

last(['jumpkick'.'roundhouse'.'uppercut']);
//=> 'uppercut'
Copy the code

Here we see a combinatorial function executing smoothly. We can operate the function from left to right on our own initiative, but the order of execution from right to left is more mathematical. Basic high school math knowledge

// Associativity
var associative = compose(f, compose(g, h)) == compose(compose(f, g), h);
// true

compose(toUpperCase, compose(head, reverse));

/ / or
compose(compose(toUpperCase, head), reverse);
Copy the code

Associative property

The nice thing about the associative law is that any group of functions can be taken apart and then packaged together in their own combinations to form new functions. Curry is our toolkit.

  • The compose, head, and reverse functions above are now used
var loudLastUpper = compose(exclaim, toUpperCase, head, reverse);

/ / or
var last = compose(head, reverse);
var loudLastUpper = compose(exclaim, toUpperCase, last);

/ / or
var last = compose(head, reverse);
var angry = compose(exclaim, toUpperCase);
var loudLastUpper = compose(angry, last);

// More variations...
Copy the code

Pointfree empty data mode

Pointfree mode stands for no data mode. Here’s a line from the 1970s movie Love Story — “Love means never having to say you’re sorry.”

  • Our pointfree model is “Pointfree style means never to say your data”.
  • Now we can implement the following Pointfree style using Currified, composite code
// Not pointfree, because data is mentioned: word
var snakeCase = function (word) {
  return word.toLowerCase().replace(/\s+/ig.'_');
};

// pointfree
var snakeCase = compose(replace(/\s+/ig.'_'), toLowerCase);

// Not sure why look at the compose function at the top and try the snakeCase function on the console

snakeCase('Hello World')
// hello_world
Copy the code

In the PointFree version, you don’t need word arguments to construct functions; On non-Pointfree versions, you must have Word to do everything.

The Pointfree pattern helps reduce unnecessary naming and keeps the code simple and generic.Copy the code

Common problems with composite code debug~

A common mistake with composition is to combine functions like map that take two arguments without a local call.

// The following functions derive the benefits of the #### associative property above

// Error: We passed an array to Angry without knowing what we passed to map.
var latin = compose(map, angry, reverse);

latin(["frog"."eyes"]);
// error


// The correct way: Each function takes an actual argument.
var latin = compose(map(angry), reverse);

latin(["frog"."eyes"]);
// ["EYES!", "FROG!"] )
Copy the code

Use trace to trace your function

var trace = curry(function(tag, x){
  console.log(tag, x);
  return x;
});

var dasherize = compose(join(The '-'), toLower, split(' '), replace(/\s{2,}/ig.' '));

dasherize('The world is a vampire');
// TypeError: Cannot read property 'apply' of undefined

--------------

// If you see an error, trace it
var dasherize = compose(join(The '-'), toLower, trace("after split"), split(' '), replace(/\s{2,}/ig.' '));
// after split [ 'The', 'world', 'is', 'a', 'vampire' ]

-------------

// The tolower argument is an array, so here we fix our code
var dasherize = compose(join(The '-'), map(toLower), split(' '), replace(/\s{2,}/ig.' '));

dasherize('The world is a vampire');

// 'the-world-is-a-vampire'
Copy the code

The advantage of trace is that it can be traced directly to the place of the function call, allowing us to view our function data at a specific point

conclusion

We can argue that composition is the design principle above all others because composition makes our code simple and readable. Categorics will also play an important role in application architecture, simulating side effects, and ensuring correctness.

  • Next article 3- Learn about JavaScript functional programming – declarative functions

Some naming methods

name demo
CamelCase (small hump) personId
PascalCase (PASCAL/Big Hump) PersonId
SnakeCase (bottom line) person_id
KebabCase (middle line) person-id

reference

  • JS functional programming guide
  • Ramda website
  • Loadsh website