Home >Web Front-end >JS Tutorial >What Is Functional Programming?

What Is Functional Programming?

William Shakespeare
William ShakespeareOriginal
2025-02-10 11:08:08635browse

What Is Functional Programming?

Core points

  • Functional programming is a programming paradigm that emphasizes invariance, first-class functions, citation transparency and pure functions. It helps write elegant, maintainable, scalable, predictable code.
  • The core principles of functional programming include pure functions (functions without side effects or operations that are not related to function output), invariance (no direct modification of data), first-class functions (functions can be used like any other value) and high Order function (a function that takes a function as one or more of its parameters, or a function that returns a function).
  • Functional programming generates modular code, which is easier to debug and test. Since function calls can be distributed across multiple cores, it can also improve computational efficiency.
  • The functional programming principle can be incorporated into any programming language and used in conjunction with other programming styles such as object-oriented programming. Even if they are not purely used, they can produce positive results in the code.

As a programmer, you may want to write elegant, maintainable, scalable, predictable code. The principles of functional programming (FP) can greatly help achieve these goals.

Functional programming is a paradigm or style that emphasizes invariance, first-class functions, citation transparency and pure functions. If you don't understand the meaning of these words, don't worry! We will break down all these terms in this article.

Functional programming originated from λ calculus, a mathematical system that revolves around function abstraction and generalization. Therefore, many functional programming languages ​​seem very mathematical. But the good news is: you don't need to use a functional programming language to apply functional programming principles to your code. In this post, we will use JavaScript, which has many features that make it suitable for functional programming without being limited to that paradigm.

Core principles of functional programming

Now that we have discussed what functional programming is, let's talk about the core principles behind FP.

Pure Function

I like to think of functions as machines - they accept input or parameters and then output something, i.e. return values. Pure functions have no "side effects" or operations that are independent of function output. Some potential side effects include printing values ​​or recording them with console.log, or manipulating variables outside the function.

This is an example of a non-pure function:

<code class="language-javascript">let number = 2;

function squareNumber() {
  number = number * number; // 非纯操作:操作函数外部的变量
  console.log(number); // 非纯操作:控制台记录值
  return number;
}

squareNumber();</code>

The following function is a pure function. It accepts input and produces output.

<code class="language-javascript">let number = 2;

function squareNumber() {
  number = number * number; // 非纯操作:操作函数外部的变量
  console.log(number); // 非纯操作:控制台记录值
  return number;
}

squareNumber();</code>

Pure functions run independently of the state outside the function, so they should not depend on global state or variables outside themselves. In the first example, we use the number variable created outside the function and set it inside the function. This violates this principle. If you rely heavily on changing global variables, your code will be unpredictable and difficult to track. It will be more difficult to find out where the error occurred and why the value changes. Instead, debugging is easier with only input, output, and function local variables.

In addition, functions should follow reference transparency, which means that given an input, their output will always be the same. In the above example function, if I pass 2 to the function, it will always return 4. This is not the case with API calls or generating random numbers, these are just two examples. Given the same input, the output may or may not be returned.

<code class="language-javascript">// 纯函数
function squareNumber(number) {
  return number * number;
}

squareNumber(2);</code>

Invariance

Functional programming also prioritizes invariability, that is, no data is modified directly. Invariance brings predictability – you know the value of the data, and they won’t change. It makes the code simple, testable, and runs on distributed and multithreaded systems.

Invariance often plays a role when we work with data structures. Many array methods in JavaScript directly modify arrays. For example, .pop() deletes an item directly from the end of the array, while .splice() allows you to get a part of the array. Instead, in the functional paradigm, we will copy the array and delete the elements we want to eliminate in the process.

<code class="language-javascript">// 不具有引用透明性
Math.random();
// 0.1406399143589343
Math.random();
// 0.26768924082159495</code>
<code class="language-javascript">// 我们直接修改 myArr
const myArr = [1, 2, 3];
myArr.pop();
// [1, 2]</code>

First-class function

In functional programming, our functions are first-class functions, which means we can use them like any other value. We can create arrays of functions, pass them as arguments to other functions, and store them in variables.

<code class="language-javascript">// 我们复制数组而不包含最后一个元素,并将其存储到变量中
let myArr = [1, 2, 3];
let myNewArr = myArr.slice(0, 2);
// [1, 2]
console.log(myArr);</code>

Advanced Order Functions

A higher-order functions are functions that perform one of two operations: they either take the function as one or more of its parameters or return the function. JavaScript has built-in many first-class higher-order functions—such as map, reduce and filter, we can use them to interact with arrays.

filter is used to return a new array from the old array that contains only values ​​that meet the conditions we provide.

<code class="language-javascript">let myFunctionArr = [() => 1 + 2, () => console.log("hi"), x => 3 * x];
myFunctionArr[2](2); // 6

const myFunction = anotherFunction => anotherFunction(20);
const secondFunction = x => x * 10;
myFunction(secondFunction); // 200</code>

map is used to iterate over items in the array and modify each item according to the provided logic. In the following example, we double each item in the array by passing a function that multiplies our value by 2 to map.

<code class="language-javascript">const myArr = [1, 2, 3, 4, 5];

const evens = myArr.filter(x => x % 2 === 0); // [2, 4]</code>

reduce allows us to output a single value based on the input array - it is usually used to sum, flatten arrays, or group values ​​in some way.

<code class="language-javascript">const myArr = [1, 2, 3, 4, 5];

const doubled = myArr.map(i => i * 2); // [2, 4, 6, 8, 10]</code>

You can also implement these functions yourself! For example, you could create a filter function like this:

<code class="language-javascript">const myArr = [1, 2, 3, 4, 5];

const sum = myArr.reduce((i, runningSum) => i + runningSum); // 15</code>

The second type of higher-order functions (functions that return other functions) is also a relatively frequent pattern. For example:

<code class="language-javascript">let number = 2;

function squareNumber() {
  number = number * number; // 非纯操作:操作函数外部的变量
  console.log(number); // 非纯操作:控制台记录值
  return number;
}

squareNumber();</code>

You may also be interested in Curry, so you can read it!

Function combination

Function combination is to combine multiple simple functions to create more complex functions. So you can have a averageArray function that combines the average function with the sum function that sums the values ​​of the array. The individual functions are small and can be repeated for other purposes and combined together to perform more complete work.

<code class="language-javascript">// 纯函数
function squareNumber(number) {
  return number * number;
}

squareNumber(2);</code>

Advantages

Functional programming generates modular code. You have a small number of functions that you can use repeatedly. Understanding the specific functions of each function means it should be simple to pinpoint errors and write tests, especially if the function output should be predictable.

Also, if you try to use multiple cores, you can distribute function calls to those cores, so it can improve computational efficiency.

How to use functional programming?

You don't need to turn completely to functional programming to integrate all of these ideas. You can even use many ideas well with object-oriented programming, which are often considered as their rival.

For example, React incorporates many functional principles, such as immutable states, but has mainly used class syntax for many years. It can also be implemented in almost any programming language - you don't need to write Clojure or Haskell unless you really want to.

Even if you are not a purist, functional programming principles can produce positive results in your code.

Frequently Asked Questions about Functional Programming

What are the key principles of functional programming?

Functional programming is based on some key principles. First is invariance, which means that once a variable is set, it cannot be changed. This eliminates side effects and makes the code easier to understand. The second principle is pure functions, which means that the output of a function is determined only by its input, without any hidden input or output. The third principle is first-class functions, which means that functions can be used as input or output to other functions. This allows for higher-order functions and makes the code more concise and easier to understand.

What is the difference between functional programming and procedural programming?

The main difference between functional and procedural programming is the way they process data and state. In procedural programming, program states are stored in variables and can be changed over time. In functional programming, the state does not change, but creates a new state from the existing state. This makes functional programming easier to predict and debug because there are no side effects to worry about.

What are the advantages of functional programming?

Functional programming provides many benefits. It can make the code easier to read and understand because it avoids side effects and mutable states. It also makes the code more reliable, as it encourages the use of pure functions that always produce the same output for the same input. In addition, functional programming can make the code easier to test and debug because functions can be tested in isolation.

What are the challenges of functional programming?

While functional programming has many benefits, it also has some challenges. It can be difficult to learn, especially for people accustomed to procedural or object-oriented programming. Implementing certain algorithms in functional style can also be more difficult. Furthermore, functional programming sometimes leads to less efficient code, as it often involves creating new objects rather than modifying existing objects.

What languages ​​support functional programming?

Many programming languages ​​support functional programming to some extent. Some languages, such as Haskell and Erlang, are purely functional, while others, such as JavaScript and Python, are multi-paradigm languages ​​that support functional programming and other paradigms. Even languages ​​traditionally unrelated to functional programming, such as Java and C, have added functionality to support functional programming in recent years.

How to deal with side effects in functional programming?

In functional programming, avoid side effects as much as possible. This is done by using pure functions that do not change any state or perform any I/O operations. When side effects are needed, they are isolated and controlled. For example, in Haskell, side effects are treated with monads, which encapsulate side effects and provide a way to link them together in a controlled way.

What are the higher-order functions in functional programming?

A higher-order function is a function that takes one or more functions as parameters, returns a function as its result, or performs both operations at the same time. Advanced-order functions are a key feature of functional programming because they allow functions to be used as data. This can lead to cleaner and more expressive code.

What is recursion in functional programming?

Recursion is a technique in which a function calls itself in its own definition. In functional programming, recursion is often used as a replacement for loops because loops involve mutable states, which is avoided in functional programming. Recursion can be used to solve a wide variety of problems, from calculating factorials to traversing trees.

What is Currying in functional programming?

Currying is a technique in functional programming in which a function with multiple parameters is converted into a series of functions, each function has only one parameter. This allows part of the function to be applied, where one function applies to some of its parameters and returns a new function that takes the rest of the parameters.

What is functional reactive programming?

Functional Reactive Programming (FRP) is a programming paradigm that combines functional and reactive programming. In FRP, program states are modeled as a series of immutable values ​​that vary over time, and functions are used to transform and combine these values. This makes it easier to reason about asynchronous and event-driven programs because it avoids mutable states and side effects.

The above is the detailed content of What Is Functional Programming?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn