게시글

강좌27 - JavaScript - 4년 전 등록 / 2년 전 수정

함수형 프로그래밍(Functional Programming)

안녕하세요. 이번 시간에는 함수형 프로그래밍에 대해서 알아보겠습니다.

사실 함수형 프로그래밍을 중급 강좌에서 다루기엔 좀 어려운 감이 있습니다만, 다음 시간의 실습을 위해 다루도록 하겠습니다.

함수형 프로그래밍은 객체지향 프로그래밍과는 다릅니다. 지금까지는 객체지향 프로그래밍을 했었죠. 객체가 기본이 되는 프로그래밍입니다. 지난 번 실습 때는 영웅 객체가 몬스터 객체를 공격했죠? 모든 것이 객체를 기반으로 돌아갑니다. 함수형 프로그래밍은 이름처럼 함수를 기반으로 돌아가겠죠? 사실 자바스크립트가 완벽하게 함수형 프로그래밍을 할 수는 없습니다. 하지만 그 스타일을 따라해보자는 거죠.

함수형 프로그래밍은 몇 가지 원칙이 있습니다. 

  • 입출력이 순수해야합니다. (순수함수)
  • 부작용(부산물)이 없어야합니다.
  • 함수와 데이터를 중점으로 생각합니다.

사실 위의 두 개는 같은 소리입니다. 입출력이 순수하다는 것은 반드시 하나 이상의 인자를 받고, 받은 인자를 처리하여 반드시 결과물을 돌려주어야한다는 겁니다. 인자를 제외한 다른 변수는 사용하면 안 됩니다. 받은 인자만으로 결과물을 내어야 하죠. 이러한 함수를 순수함수라고 부릅니다. 자바스크립트는 this라는 개념 때문에 (this를 어쩔 수 없이 사용해야하는 상황) 순수함수를 사용하기 힘듭니다. 그래도 최대한 비슷하게 할 수는 있죠.

부작용이 없어야한다는 것은, 프로그래머가 바꾸고자하는 변수 외에는 바뀌어서는 안 된다는 뜻입니다. 원본 데이터는 불변해야함을 기억하세요! 함수형 프로그래밍에서는 프로그래머가 모든 것을 예측하고 통제할 수 있어야합니다. 어렵죠?

반복문 대신에 재귀함수를 사용하는 것은 아래에 예시로 보여드릴게요.

대표적인 함수형 프로그래밍 함수들이 있습니다. map, filterreduce죠. 배열에 있는 메소드란 거는 아시죠? 이 두 메소드를 살펴봅시다.

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

함수형 프로그래밍은 지금까지 객체지향 프로그래밍을 했던 사람들에게는 매우 생소한 개념일 겁니다. 하지만 이러한 접근 방식도 있다는 것을 알아두세요!

이상으로 중급 강좌를 마칩니다! 사실 중급이지만 다 배웠다고 해도 될 정도입니다. 고급 강좌 시간에는 여러가지 팁과 지금까지 다루지 못했던 것들을 다룰거니까요. 다음 시간에는 지금까지 배운 모든 것을 활용해서 턴제 게임을 만들어보겠습니다!

조회수:
0
목록
투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.

댓글

3개의 댓글이 있습니다.
2년 전
함수로 반복문 사용시
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이 다른거죠?
2년 전
앗, 그 부분 없어도 되네요. 감사합니다.
3년 전
이렇게 자세히 설명해주셔서 감사합니다.
4년 전
선생님, 마지막 예시 중에 var time = 10; 의 용도가 무엇인가요? 코드 중에 count와 연관이 있나요?
4년 전
var time = 10;을 삭제하고 add(0, 10);을 해도 55의 결과값이 나오는데 어떤 특수한 목적이 있어서 삽입한 것인지 알고 싶습니다.
4년 전
아 time은 관련이 없습니다