Functional programming

Functional programming

Why should we learn functional programming and what it is, including the characteristics of functional programming (pure function, coritization, function combination, etc.)
Functional programming is to use pure functions to realize some fine-grained functions, and then combine these fine-grained functions into more powerful functions through the combination of functions

Why learn functional programming

Functional programming is a very old concept, which predates the birth of the first computer. Interested students can search by themselves. Why should we learn functional programming? Let's briefly explain it based on the following points:
  • With the popularity of React, functional programming has attracted more and more attention
  • Vue 3 is also embracing functional programming
  • Functional programming can abandon this
  • In the packaging process, we can make better use of tree shaking to filter useless code
  • Convenient for testing and parallel processing
  • There are many libraries that can help us with functional development: lodash, underscore, and ramda
Functional programming (FP) is one of the programming paradigms. We often hear of programming paradigms such as process oriented programming and object-oriented programming. Thinking mode of functional programming: abstract things in the real world and the relationship between things to the program world (abstract the operation process), and use a piece of code to briefly demonstrate it
// Sum
// Non functional formula
let num1 = 1
let num2 = 2
let sum = num1 + num2
console.log(sum)

// Functional formula
function add (n1, n2) {
    return n1 + n2
}
let sum = add(1, 2)
console.log(sum)
// In addition, the function in functional programming refers not to the function (method) in the program, but to the function in mathematics, that is, the mapping relationship, and requires the same input to always have the same output

Pre knowledge of functional programming

1, The function is a first-class citizen with several points:
  • Functions can be stored in variables
  • Function as parameter
  • Function as return value
2, Higher order functions have two definitions:
  • You can pass a function as an argument to another function (such as the forEach method of an array, let's take an example)
// Simulate forEach
function forEach(arr, fn) {
    for(let i = 0; i < arr.length; i++) {
        fn(arr[i])
    }
}
// test
let arr = [1, 2, 3, 4]
forEach(arr, function (item) {
    console.log(item)
})
// Results 1 2 3 4
  • Function as return value
function makeFn () {
    let msg = 'Hello'
    return function () {
        console.log(msg)
    }
}

const fn = makeFn()
fn()
// Hello result

The meaning of higher-order functions is mainly abstract and general problems. For example, for forEach, we don't need to pay attention to the specific implementation of the loop, we just need to do what we want to achieve.
3, Closure:
  • You can call an internal function of a function in another scope and access members in the scope of the function.
  • Essence: when a function is executed, it will be placed on an execution stack. When the function is executed, it will be removed from the execution stack, but
    Scope members on the heap cannot be released because they are externally referenced, so internal functions can still access members of external functions

The core concept of functional programming

The previous introduction is the basis. Next, we will talk about the first core, pure function
Pure functions say that the same input will always get the same output without any observable side effects., For example, the array operation methods slice and splice:
  • slice returns the specified part of the array without changing the original array (pure function)
  • splice operates on the array and returns the array, which will change the original array
Advantages of pure function: it can be cached. Because pure function always has the same result for the same input, the result of pure function can be cached
function memoize(f) {
    let cache = {}
    return function () {
        let key = JSON.stringify(arguments)
        cache[key] = cache[key] || f.apply(f, arguments)
        return cache[key]
    }
}
If the pure function depends on the external state, the output cannot be guaranteed to be the same, which will bring side effects.
The second is function coritization: represented by a simple piece of code
function getSum (a, b, c) {
    return a + b + c
}

function curry (func) {
    return function curriedFn(...args) {
        // Determine the number of arguments and formal parameters
        if(args.length < func.length) {
            return function () {
                return curriedFn(...args.concat(Array.from(arguments)))
            }
        }
        return func(...args)
    }
}

const curried = curry(getSum)

console.log(curried(1, 2, 3))
console.log(curried(1)(2, 3))
console.log(curried(1, 2)(3))
// 6 6 6
  • Coriolism allows us to pass fewer parameters to a function and get a new function that has remembered some fixed parameters
  • This is a cache of function parameters
  • Make the function more flexible and make the granularity of the function smaller
  • It can convert multivariate functions into univariate functions, and can combine functions to produce powerful functions
The third is function combination: pure function and Coriolis can easily write onion code H (g (f (x)), for example, get the last element of the array and convert it into uppercase letters, XX Toupper (XX. First (XX. Reverse (array))), and function combination allows us to recombine fine-grained functions to generate a new function. The concept is as follows:
  • If a function needs to be processed by multiple functions to get the final value, the functions of the intermediate process can be combined into one function at this time
  • Functions are like pipelines of data. Function combination is to connect these pipelines and let the data pass through multiple pipelines to form the final result
  • Function combinations are executed from right to left by default
  • for instance
// Combinatorial function
function compose (f, g) {
    return function(value) {
        return f(g(value))
    }
}

function reverse (array) {
    return array.reverse()
}

function first (array) {
    return array[0]
}

const last = compose(first, reverse)
console.log(last([1, 2, 3, 4]))
// Result 4
Although this code is troublesome, these auxiliary functions can be combined arbitrarily. Therefore, functional programming can be reused to the greatest extent

Tags: Javascript

Posted by disconne on Sun, 15 May 2022 13:58:51 +0300