안녕하세요. 이번 시간에는 함수형 프로그래밍에 대해서 알아보겠습니다.
사실 함수형 프로그래밍을 중급 강좌에서 다루기엔 좀 어려운 감이 있습니다만, 다음 시간의 실습을 위해 다루도록 하겠습니다.
함수형 프로그래밍은 객체지향 프로그래밍과는 다릅니다. 지금까지는 객체지향 프로그래밍을 했었죠. 객체가 기본이 되는 프로그래밍입니다. 지난 번 실습 때는 영웅 객체가 몬스터 객체를 공격했죠? 모든 것이 객체를 기반으로 돌아갑니다. 함수형 프로그래밍은 이름처럼 함수를 기반으로 돌아가겠죠? 사실 자바스크립트가 완벽하게 함수형 프로그래밍을 할 수는 없습니다. 하지만 그 스타일을 따라해보자는 거죠.
함수형 프로그래밍은 몇 가지 원칙이 있습니다.
- 입출력이 순수해야합니다. (순수함수)
- 부작용(부산물)이 없어야합니다.
- 함수와 데이터를 중점으로 생각합니다.
사실 위의 두 개는 같은 소리입니다. 입출력이 순수하다는 것은 반드시 하나 이상의 인자를 받고, 받은 인자를 처리하여 반드시 결과물을 돌려주어야한다는 겁니다. 인자를 제외한 다른 변수는 사용하면 안 됩니다. 받은 인자만으로 결과물을 내어야 하죠. 이러한 함수를 순수함수라고 부릅니다. 자바스크립트는 this라는 개념 때문에 (this를 어쩔 수 없이 사용해야하는 상황) 순수함수를 사용하기 힘듭니다. 그래도 최대한 비슷하게 할 수는 있죠.
부작용이 없어야한다는 것은, 프로그래머가 바꾸고자하는 변수 외에는 바뀌어서는 안 된다는 뜻입니다. 원본 데이터는 불변해야함을 기억하세요! 함수형 프로그래밍에서는 프로그래머가 모든 것을 예측하고 통제할 수 있어야합니다. 어렵죠?
반복문 대신에 재귀함수를 사용하는 것은 아래에 예시로 보여드릴게요.
대표적인 함수형 프로그래밍 함수들이 있습니다. map, filter와 reduce죠. 배열에 있는 메소드란 거는 아시죠? 이 두 메소드를 살펴봅시다.
var arr = [1, 2, 3, 4, 5];
var map = arr.map(function(x) {
return x * 2;
}); // [2, 4, 6, 8, 10]
처음에 배열(arr)을 넣어서(입력), 결과(map)를 얻었습니다(출력). arr도 사용은 됐지만, 값은 변하지 않았고, map이라는 결과를 내고 아무런 부작용도 낳지 않았습니다. 바로 이런 게 함수형 프로그래밍에 적합한 함수, 순수함수입니다. 물론 이것은 배열의 메소드지만, 충분히 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
함수형 프로그래밍은 지금까지 객체지향 프로그래밍을 했던 사람들에게는 매우 생소한 개념일 겁니다. 하지만 이러한 접근 방식도 있다는 것을 알아두세요!
이상으로 중급 강좌를 마칩니다! 사실 중급이지만 다 배웠다고 해도 될 정도입니다. 고급 강좌 시간에는 여러가지 팁과 지금까지 다루지 못했던 것들을 다룰거니까요. 다음 시간에는 지금까지 배운 모든 것을 활용해서 턴제 게임을 만들어보겠습니다!
var sum = 0;
function add(sum, count) {
sum += count;
if (count > 0) {
return add(sum, count - 1);
} else {
return sum;
}
}
add(0, 10); // 55
var sum =0; 이 없어도 55가 출력이 됩니다. 변수 sum과 함수에 인자로 들어간 sum이 다른거죠?