자바스크립트를 활용한 함수형 프로그래밍

Marco·2022년 1월 20일
0

Javascript TIL

목록 보기
10/12
post-thumbnail

1. 함수형 프로그래밍 개요

함수형 프로그래밍 기법은 리액트 뿐 아니라 리액트 생태계를 이루는 여러 라이브러리의 근간이다.

함수가 1급 시민이 되면 변수에 함수를 대입할 수 있고, 함수를 다른 함수에 인자로 넘길 수 있으며, 함수에서 함수를 만들어서 반환할 수 있어야 한다.

자바스크립트에서는 함수가 1급 시민이기 때문에, 자바스크립트가 함수형 프로그래밍을 지원한다고 말할 수 있다. 1급 시민이라는 말은 정수나 문자열 같은 다른 일반적인 값과 마찬가지로 함수를 취급할 수 있다는 뜻이다.

함수를 객체, 배열, 다른 함수의 인자에 넣을 수 있다. 또한, 함수가 함수를 반환할 수 있다.

특히, 함수가 함수를 인자로 받는 경우와 함수가 함수를 반환하는 경우를 고차함수 라고 부른다.

// 위 고차함수를 화살표 함수로 표현
const createScream = logger => message => {
	logger(message.toUpperCase() + "!!!");
};

이처럼 함수에 2개 이상의 화살표가 있다면 고차 함수를 사용하고 있다는 뜻이다.

2 명령형 프로그래밍과 선언적 프로그래밍 비교

프로그래밍 패러다임을 크게 선언적 프로그래밍명령형 프로그래밍으로 나눌 수 있다.

함수형 프로그래밍은 선언적 프로그래밍 의 방법 중 하나이다.

  • 선언적(declarative) 프로그래밍필요한 것을 달성하는 과정을 하나하나 기술하는 것보다 필요한 것이 어떤 것인지를 기술하는 것에 더 방점을 두고 애플리케이션 구조를 세워나가는 프로그래밍 스타일이다.
    • 선언적 프로그래밍의 코드 구문은 어떤 일이 발생해야 하는지에 대해 기술하고, 실제로 그 작업을 처리하는 방법은 추상화를 통해 아랫단에 감춰진다.
    • 선언적 접근 방식이 더 읽기 쉽고, 그렇기 때문에 더 추론하기 쉽고, 그 애플리케이션의 규모를 확장하는 것도 더 쉽다.
  • 명령형(imperative) 프로그래밍 은 코드로 원하는 결과를 달성해 나가는 과정에만 관심을 두는 프로그래밍 스타일이다.

3 함수형 프로그래밍의 개념

함수형 프로그래밍의 핵심 개념으로 불변성(immutability), 순수성(purity), 데이터 변환(transformation), 고차 함수, 재귀(recursion) 등이 있다.

3.1 불변성

함수형 프로그래밍에서는 데이터가 변할 수 없다.

그래서 원본 데이터 구조를 변경하는 대신 그 데이터 구조의 복사본을 만들되 그중 일부를 변경한다.

그리고 원본 대신 변경한 복사본을 사용해 필요한 작업을 진행한다.

[객체]

const ratecolor = (color, rating) => ({
	...color,
	rating
});

[배열]

const addColor = (title, list) => [...list, {title}];

3.2 순수 함수

순수 함수(Pure Functions)는 파라미터에 의해서만 반환값이 결정되는 함수를 뜻한다. 이는 함수형 프로그램의 핵심 개념 중 하나이다.

  • 순수함수에는 부수 효과(side effect)가 없다.

    • 부수 효과란 전역 변수를 설정하거나, 함수 내부나 애플리케이션에 있는 다른 상태를 변경하는 것을 말한다.
    • 순수 함수는 인수를 변경 불가능한 데이터로 취급한다.
  • 순수함수 규칙

    1. 순수 함수는 파라미터를 최소한 하나 이상 받아야 한다.
    2. 순수 함수는 값이나 다른 함수를 반환해야 한다.
    3. 순수 함수는 인자나 밖에 있는 다른 변수를 변경하거나, 입출력을 수행해서는 안된다.
  • 리액트에서는 UI를 순수 함수로 표현한다.

  • 순수 함수를 사용하면 애플리케이션의 상태에 영향을 미치지 않기 때문에 코딩이 편해진다.

다음은 DOM을 변경하는 순수하지 않는 함수의 예시이다.

  • 이 함수는 함수나 값을 반환하지 않으며(규칙2 위반), DOM을 변경하는 부수 효과를 발생시키기(규칙3 위반) 때문에, 순수하지 않은 함수이다.
function Header(text) {
	let h1 = document.createElement('h1');
	h1.innerText = text;
	document.body.appendChild(h1);
}

Header("안녕");
  • 리액트 등에서 UI로 사용할 순수함수의 예시는 다음과 같다. 부수 효과를 발생시키지 않고 엘리먼트를 반환한다. 이 함수는 엘리먼트를 만드는 일만 책임지며, DOM을 변경하는 책임은 애플리케이션의 다른 부분이 담당해야 한다.
const Header = (props) => <h1>{props.title}</h1>

3.3 데이터 변환

  • 함수형 프로그래밍은 한 데이터를 다른 데이터로 변환하는 것이 전부다.
  • 함수형 프로그래밍은 함수를 사용해 원본을 변경한 복사본을 만들어낸다.
    • 그런 식으로 순수 함수를 사용해 데이터를 변경하면, 코드가 덜 명령형이 되고 그에 따라 복잡도도 감소한다.

자바스크립트 내장 함수를 사용하여 데이터 변환하여 다른 데이터를 만들어낼 수 있다.

새 값을 반환하는 Array.join, Array.filter, Array.map, Array.reduce, Array.reduceRight

3.4 고차 함수

고차 함수는 다른 함수를 조작할 수 있는 함수다.

고차함수는 다른 함수를 인자로 받을 수 있거나 함수를 반환할 수 있고, 때로는 그 2가지를 모두 수행한다.

예를 들어, Array.map, Array.filter, Array.reduce는 다른 함수를 인자로 받기 때문에, 모두 고차 함수다.

다른 함수를 반환하는 고차 함수는 자바스크립트에서 비동기적인 실행 맥락을 처리할 때 유용하다. 함수를 반환하는 고차 함수를 쓰면 필요할 대 재활용할 수 있는 함수를 만들 수 있다.

  • 커링
    • 커링(Currying) 은 고차 함수 사용법과 관련한 함수형 프로그래밍 기법이다.
    • 커링은 어떤 연산을 수행할 때 필요한 값 중 일부를 저장하고, 나중에 나머지 값을 전달받는 기법이다. 이를 위해 다른 함수를 반환하는 함수를 사용하며, 이를 커링된 함수(Curried fucntion) 라고 부른다.

3.5 재귀

재귀는 비동기 프로세스에서도 잘 작동하는 또 다른 함수형 기법이다. 함수는 필요할 때 자기 자신을 다시 호출할 수 있다.

3.6 합성

함수형 프로그램은 로직을 구체적인 작업을 담당하는 여러 작은 순수 함수로 나눈다. 그 과정에서 언젠가는 모든 작은 함수를 한데 합칠 필요가 있다.

합성 방법으로 체이닝 등이 있으나, 함수를 더 큰 함수로 조합해주는 compose와 같은 커스텀 함수를 사용할 수 있다.

compose는 여러 함수를 인자로 받아서 한 함수를 결과로 내놓는다.

  • compose 함수 예시
const compose = (...fns) => (arg) => 
	fns.reduce((composed, f) => f(composed), arg);

const funcFirst = (word) => `{${word}}`

const funcSecond = (word) => `[${word}]`

const both = compose(
	funcFirst,
	funcSecond
);

console.log(both('hello')) // [{hello}]

책 [러닝 리액트]에서 발췌 요약한 내용입니다.

profile
블로그 이사 🚚 https://wonsss.github.io/

0개의 댓글