함수형 프로그래밍 #01 | 함수형 프로그래밍과 부수효과
2022년 08월 31일 15:52
📌 함수형 프로그래밍의 핵심
함수형 프로그래밍은 프로그램을 작은 순수함수들로 분리하고 각각의 함수들을 서로 합성하여 더 큰 프로그램을 만드는 것이다. 불변성, 일급함수, 게으름 평가, 수학적 이론등은 잘 합성하기 위한 도구인 것이다. 아래는 핵심개념 2가지
- 함수를 합성해서 복잡한 프로그램을 쉽게 만들기
- 부수효과(Side effect)를 찾아내고 이걸 분리해서 공통적인 방법으로 추상화하는 것
📌 명령형 vs 함수형
-
명령형: 기계에게 효율적인 방식이고, 부수효과 복잡
근본: 튜링머신(임의의 메모리를 수정하여 계산)
-
함수형: 사람이 이해하기 쉽고, 부수효과가 없는 순수 함수 (뭐가 나올지 알고 정직하다.)
근본: 람다대수(변수와 함수만으로 모든 걸 계산)
명령형으로 작성하면 반드시 함수형으로 작성할 수 있다.
📌 객체지향 vs 함수형
- 객체지향: 움직이는 부분을 캡슐화하여 코드 이해를 돕는다.
- 함수형: 움직이는 부분을 최소화하여 코드 이해를 돕는다.
OOP와 함수적 계산은 완전히 조화될 수 있습니다. (그리고 그래야만 하죠) - Alan Kay
📌 부수효과를 최소화 하는 이유
부수효과란 값을 변환하는 것 외에 부수적으로 일으키는 효과를 말하며, 부수효과 생기고 비동기나 병렬 처리, 전역 상태까지 더해진다면 코드를 이해하고 결과를 예측하기는 더더욱 어려워진다. 따라서 객체지향이나 절차적프로그래밍 패러다임이 나온 것이다.
📌 순수함수
주어진 입력에 대해 계산 수행하고 리턴하는 역할만 하는 부수효과가 없는 함수로, 기존에 쓰는 함수와 구분하기 위해 순수함수라 부른다.
수학적 의미의 함수와 동일하기 때문에 이미 증명된 것들을 안전하게 사용할 수 있다.
for나 while같은 구문은 상태 변경하고 불변성을 유발하기 때문에 사용이 불가능하고, 반복이 필요할 때에는 재귀를 통해 해결을 하곤 한다.
각각의 함수가 버그가 없으면 합성한 함수도 버그가 없다는걸 알 수 있다.
📌 “sum 1 to 100”을 순수함수로 다듬기
//명령형
function sum_1_to_100() {
let sum = 0;
for (let i = 1; i <= 100; i++) {
sum += 1;
}
return sum;
}
//순수함수긴 한데... 복잡
function sum_1_to_100() {
function go(sum, i) {
if (i > 100) {
return sum;
}
return go(sum + i, i + 1);
}
return go(0, 1);
}
console.log(sum_1_to_100());
//일반화된 방식으로 추상화(선언적이고, 합성이 쉽다)(Category 이론의 수학적 증명에 기반)
function loop(fn, acc, list) {
if (list.length === 0) return acc;
const [head, ...tail] = list;
return loop(fn, fn(acc, head), tail);
}
const range = (start, end) => Array.from(
{length: end - start + 1},
(_, index) => index + start
);
const plus = (a, b) => a + b;
const result = loop(plus, 0, range(1, 100));각각의 함수는 특정 입력에 같은 결과를 return하게 된다.
마지막에 만든 loop는 사실상 reduce함수와 같다.
range(1, 100).reduce((acc, cur) => acc + cur, 0);