Started contact with functional programming time is the time to work in millet, the time to see the boss before writing the code composer, and then some ramda tools function, watching with difficulty, and then tried to ridicule functional programming, in retrospect, that time really is the pointy-haired myself, just want to say, ‘delicious’.

Recently, I have been studying functional programming. In the process of learning, I really feel that my thinking has been improved a lot, and my abstract ability has been greatly improved, which makes me deeply feel the charm of functional programming. So I’m going to spend the next five to eight articles covering the idea of functional programming, the basics, how to design it, how to test it, and so on.

Today’s article focuses on the idea of functional programming.

  • Does functional programming work?
  • What is functional programming?
  • Advantages of functional programming.

Object-oriented programming (OOP) makes code easier to understand by encapsulating changes. Functional programming (FP) makes code easier to understand by minimizing change. — Michacel Feathers (Twitter)

As we all know, JavaScript is a dynamic language with a lot of shared state, and over time, the code accumulates enough complexity to become unwiely and difficult to maintain. Object-oriented design can help us solve this problem to some extent, but it’s not enough.

Because there are a lot of states, it’s very important to deal with the flow of data and the passing of changes, and I don’t know if you know about reactive programming, which is a programming paradigm that helps deal with asynchronous or event responses in JavaScript. In conclusion, when designing an application, we should consider whether the following design principles are followed.

  • Extensibility – do I need to constantly refactor code to support additional functionality?
  • Easy modularity – if I change one file, will another be affected?
  • Reusability – Is there a lot of duplicate code?
  • Testability – Am I struggling to add unit tests to these functions?
  • Rationalization – Is my code unstructured and hard to reason with?

I can tell you this, once you learn functional programming, these problems will be solved, that’s the idea, once you learn functional programming, and then you learn responsive programming it’s a lot easier to understand, and THAT’s what I’ve learned. I really had a hard time learning Rxjs. To be honest, Rxjs is one of the most difficult libraries I’ve ever learned. After a painful month or two, some things still didn’t sink in until I recently took functional programming for granted. Without exaggeration, I will try to introduce you to Rxjs in the next article, a topic I also shared at the company.

What is functional programming?

Simply put, functional programming is a style of software development that emphasizes the use of functions. I don’t know what functional programming is. Don’t worry. I believe you will understand by the end.

Also keep in mind that the purpose of functional programming is to use functions to abstract the flow of control and operations on the data, thereby eliminating side effects and reducing state changes in the system.

Let’s use an example to briefly demonstrate the power of functional programming.

Now the requirement is to output “Hello World” on the web page.

Maybe a beginner would write it this way.

document.querySelector('#msg').innerHTML = '<h1>Hello World</h1>'
Copy the code

This program is simple, but all the code is dead and unreusable, and changing the format, content, etc. of the message requires rewriting the entire expression, so it’s possible that an experienced front-end developer would write this.

function printMessage(elementId, format, message) {
    document.querySelector(elementId).innerHTML = ` <${format}>${message}</${format}> `
}

printMessage('msg'.'h1'.'Hello World')
Copy the code

That’s an improvement, but it’s still not a piece of reusable code if I’m writing text to a file that’s not non-HTML, or if I want to repeat Hello World.

So how would a functional developer write this code?

const printMessage = compose(addToDom('msg'), h1, echo)

printMessage('Hello World')
Copy the code

Just to explain this code, h1 and echo are both functions, and addToDom is clearly a function, so why did we write it like this? It looks like a lot more functions.

What we’re really talking about is breaking the program down into more reusable, more reliable, and easier to understand parts, and then putting them together to form a more reasoning whole, which is the basic principle we talked about earlier.

For compose, the function will be executed from the last parameter to the first parameter, and each parameter of compose is a function. If you don’t know, you can check it out. This is the essence in the middleware part of Redux.

As you can see, we split a task into several functions with the smallest particles and then combine them to complete our task. This is very similar to our componentization idea, which is to break the entire page into several components and then assemble them to complete our entire page. In functional programming, composition is a very, very, very important idea.

Ok, so let’s change the requirements again, and now we need to repeat the text three times and print it to the console.

var printMessaage = compose(console.log, repeat(3), echo) printMessage (" Hello World ")Copy the code

You can see that we changed the requirements without modifying the internal logic, just reorganizing the function.

You can see that functional programming has a declarative pattern in development. To fully understand functional programming, let’s look at a few basic concepts.

  • Declarative programming
  • Pure functions
  • Reference transparent
  • immutability

Declarative programming

Functional programming belongs to the declarative programming paradigm: the paradigm describes a set of operations, but does not reveal how they are implemented or how data flows through them.

The familiar SQL statement is a very typical declarative programming, which is composed of assertions describing what the query result should be, and abstracts the internal mechanism of data retrieval.

Let’s look at one more set of code and compare imperative and declarative programming.

// Command mode
var array = [0.1.2.3]
for(let i = 0; i < array.length; i++) {
    array[i] = Math.pow(array[i], 2)
}

array; // [0, 1, 4, 9]

// Declarative
[0.1.2.3].map(num= > Math.pow(num, 2))
Copy the code

You can see that imperative is very specific in telling the computer how to perform a task.

Declarative separates the description of a program from its evaluation. It is concerned with how program logic can be described in various expressions without necessarily indicating changes in its control flow or state relationships.

Why did we get rid of the code loop? A loop is an important command control structure, but it is difficult to reuse and insert into other operations. Functional programming is designed to make code as stateless and invariable as possible. To do this, learn to use functions without side effects — also known as pure functions

Pure functions

A pure function is one that has no side effects. The same input has the same output, just like the functions we learned.

Often these conditions have side effects.

  • To change a global variable, property, or data structure
  • Changes the original value of a function argument
  • Processing user input
  • Throw an exception
  • Screen printing or logging
  • Query HTML documents, browser cookies or access databases

Here’s a simple example

var counter = 0
function increment() {
    return ++counter;
}
Copy the code

So this function is impile, so it reads the external variable, so you might think that this code is fine, but it’s hard to predict what you’re doing when you’re relying on the external variable, and you might have changed counter elsewhere, so that what you increment is not what you expected.

For pure functions there are the following properties:

  • Depends only on the input provided and not on any hidden and external states that may change between function evaluation or calls.
  • No out-of-scope changes are made, such as modifying global variables or parameters passed by reference.

However, some side effects are unavoidable in our daily development, such as interacting with external storage systems or DOM, but we can make them easier to manage by separating them from the main logic.

Now we have a small requirement: find the student’s record by ID and render it in the browser (write the program thinking that it might also be written to the console, database or file, so think about how to reuse your code).

// Imperative code

function showStudent(id) {
    // If this is a synchronous query
    var student = db.get(id)
    if(student ! = =null) {
          // Read the external elementId
          document.querySelector(`${elementId}`).innerHTML = `${student.id}.${student.name}.${student.lastname}`
    } else {
        throw new Error('not found')
    }
}

showStudent('666')

// Functional code

// Use the find function to find students
var find = curry(function(db, id) {
    var obj = db.get(id)
    if(obj === null) {
        throw new Error('not fount')}return obj
})

// Set the student object format
var csv = (student) = > `${student.id}.${student.name}.${student.lastname}`

// Display on the screen
var append = curry(function(elementId, info) {
    document.querySelector(elementId).innerHTML = info
})

var showStudent = compose(append('#student-info'), csv, find(db))

showStudent('666')
Copy the code

If you don’t understand curry, don’t worry, it’s a tricky concept for beginners that plays a crucial role in functional programming.

You can see that the functional code writes showStudent as a combination of smaller functions by reducing the length of these functions. It’s not perfect, but it does show a lot of advantages over imperative.

  • Flexible. There are three reusable components
  • The declarative style provides a clear view of the higher-order steps and enhances the readability of the code
  • The other is to separate pure functions from impure behavior.

We see that the output of pure functions is consistent, predictable, the same input will have the same return value, which is also called reference transparency.

Reference transparent

Reference transparency is the correct way to define a pure function. Purity in this sense represents the pure relationship of the mapping between a function’s arguments and its return value. A function is said to be reference transparent if it consistently produces the same result for the same input.

The concept is easy to understand, just give two simple examples.

// Unreferenced transparency
var counter = 0

function increment() {
    return ++counter
}

// Reference transparency
var increment = (counter) = > counter + 1
Copy the code

In fact, arrow functions have a fancy name in functional programming, called lambda expressions, and these anonymous functions are technically called lambda expressions, which are now supported in Java.

Immutable data

Immutable data is data that cannot be changed after it is created. In JavaScript, as in many other languages, some basic types (String,Number, etc.) are essentially immutable, but objects are mutable anywhere.

Consider a simple array sort code:

var sortDesc = function(arr) {
    return arr.sort(function(a, b) {
        return a - b
    })
}

var arr = [1.3.2]
sortDesc(arr) / / [1, 2, 3]
arr / / [1, 2, 3]
Copy the code

This code looks fine, but it has the side effect of changing the original reference to [1, 2, 3] during the sorting process. This is a language defect, and we’ll see how to overcome it later.

conclusion

  • Code that uses pure functions never changes or breaks global state, which helps make your code more testable and maintainable
  • Functional programming adopts a declarative style, making it easier to reason, and improving the readability of the code.
  • Functional programming treats functions as building blocks, using higher-order functions to make code more modular and reusable.
  • Reactive programming can be used to combine functions to reduce the complexity of event drivers (a separate article later, perhaps).

The JavaScript Functional Programming Guide

Welcome to pay attention to the personal public number [front Taoyuan], public update frequency faster than nuggets.