입출력이 순수하다는 것은 반드시 하나 이상의 인자를 받고, 받은 인자를 처리하여 반드시 결과물을 돌려주어야한다는 겁니다. 받은 인자만으로 결과물을 내어야 하죠. 이러한 함수를 순수함수라고 부릅니다.
부작용이 없어야한다는 것은, 프로그래머가 바꾸고자하는 변수 외에는 바뀌어서는 안 된다는 뜻입니다. 원본 데이터는 불변해야함을 기억하세요! 함수형 프로그래밍에서는 프로그래머가 모든 것을 예측하고 통제할 수 있어야합니다.
var arr = [1, 2, 3, 4, 5];
var map = arr.map(function(x) {
return x * 2;
}); // [2, 4, 6, 8, 10]
바로 이런 게 함수형 프로그래밍에 적합한 함수, 순수함수입니다. 물론 이것은 배열의 메소드지만, 충분히 map이라는 함수를 따로 만들 수 있습니다.
다른 예를 볼까요?
var arr = [1, 2, 3, 4, 5];
var condition = function(x) { return x % 2 === 0; }
var ex = function(array) {
return array.filter(condition);
};
ex(arr); // [2, 4]
위의 ex함수는 순수함수일까요? 언뜻 보면 맞는 것 같은데 아닙니다. 바로 condition 변수 때문이죠. 인자로 받지 않은 변수를 사용했습니다. 위의 ex함수를 순수함수로 바꾸려면
var ex = function(array, cond) {
return array.filter(cond);
};
ex(arr, condition);
condition 변수 또한 인자로 받으면 됩니다. 이렇게 하면 쉽게 에러를 추적할 수 있습니다. 인자가 문제였거나, 함수 내부가 문제였거나 둘 중 하나이기 때문이죠.
반복문을 사용하지 말라고 했는데 그렇다면 어떻게 처리해야할 지 보여드리겠습니다. 보통이라면 1부터 10까지 더할 때
var sum = 0;
for (var i = 1; i <= 10; i++) {
sum += i;
}
이렇게 많이 하는데요. 함수형 프로그래밍에서는 다음과 같이 합니다.
function add(sum, count) {
sum += count;
if (count > 0) {
return add(sum, count - 1);
} else {
return sum;
}
}
add(0, 10); // 55
add 안에서 add를 또 호출하네요. 복잡해보이지만 한 번 실행 결과를 잘 생각해보세요. 이렇게 함수형으로 표현하면 장점이, 코드의 재사용성이 매우 높아진다는 겁니다. 한 번 함수로 만들어놓으면 언제든지 add 함수를 다시 쓸 수 있으니까요.
reduce 메소드를 쓸 수도 있습니다. 좀더 함수형 프로그래밍다운 방법입니다.
var arr = [1,2,3,4,5,6,7,8,9,10];
arr.reduce(function(prev, cur) {
return prev + cur;
}); // 55
함수형 프로그래밍은 지금까지 객체지향 프로그래밍을 했던 사람들에게는 매우 생소한 개념일 겁니다. 하지만 이러한 접근 방식도 있다는 것을 알아두세요!
참고
https://www.zerocho.com/category/JavaScript/post/576cafb45eb04d4c1aa35078