정의

데이터를 함수로 연결하고 계산하는 것을 중시하는 프로그래밍 패러다임

특징

1. 순수함수

  • 동일한 입력에는 항상 동일한 값을 반환해야 한다.
  • 함수 내부에서 전달받은 인자의 값을 변경하거나,
    외부의 값을 변경하는 Side Effect가 없어야 한다.
// 비순수함수
let num = 10;

function multiply(a) {
    return a * num;
}

전역 변수인 num의 값이 바뀌면 리턴값이 달라지므로, 순수함수라고 할 수 없다.

// 순수함수
function multiply(a, b) {
    return a * b;
}

함수의 실행이 외부의 값에 영향을 미치지 않고,
동일한 입력에 대하여 동일한 리턴값을 가지므로 순수함수라고 할 수 있다.

2. 불변성

  • 데이터는 변하지 않는 불변성을 유지해야 한다.
  • 데이터의 변경이 필요한 경우, 원본 데이터의 복사본을 만들어 사용한다.
// Bad
const user = { name: "gihong", level: 1 };

function increaseLevel(user) {
    user.level += 1;
    return user;
}

user 객체의 속성이 변경되었다. 불변성을 지키지 못한 사례다.

// Good
const user = { name: "gihong", level: 1 };

function increaseLevel(user) {
    return { ...user, level: user.level + 1 };
}

원본 데이터의 복사본을 만들어 사용한다. 불변성을 만족하였다.

3. 일급 객체

함수는 일급 객체이어야 한다. 이는 다음과 같은 의미다.

  • 함수를 변수 또는 객체와 같은 자료구조에 저장할 수 있다.
  • 함수의 매개변수에 전달할 수 있다. (고차함수)
  • 함수의 리턴값으로 사용할 수 있다. (고차함수)
// 일급 객체로서의 함수
const add = (num) => num + 2;
const multiply = (num) => num * 2;
const transform = (numbers) => numbers.map(add).map(multiply);

console.log(transform([0, 1, 2, 3])); // [4, 6, 8, 10]

4. 선언형 프로그래밍

명령형 프로그래밍은 무엇을 어떻게 할 것인가에 주목하고,
선언형 프로그래밍은 무엇을 할 것인가에 주목한다.

// 명령형 프로그래밍
const numbers = [0, 1, 2];

function addFive(numbers) {
    for (let i = 0; i < numbers.length; i++) {
        numbers[i] = numbes[i] + 5;
    }
}

이와는 다르게
선언형 프로그래밍에서는 if, for, switch 등이 아닌 함수형 코드를 사용해야 한다.

// 선언형 프로그래밍
function addFive(number) {
    return number.map((num) => num + 5);
}

장점

  • 높은 수준의 추상화
  • 함수 단위의 코드 재사용
  • 불변성을 지향하므로 동작을 예측하기 쉬워짐

단점

  • 순수함수 구현 시 코드의 가독성이 나빠질 수 있음
  • 여러 개의 순수함수를 조합하는 것이 어려움

참고자료

함수형 프로그래밍 - 위키백과, 우리 모두의 백과사전
함수형 프로그래밍이란?