함수형 프로그래밍

fromzoo·2021년 1월 12일
0

함수형 프로그래밍이란?

함수를 이용하여 프로그래밍 하는 것.

  • 부수효과 없는 프로그래밍
    - 인자를 받고 그에 따른 결과물을 내놓음
    - 함수 내부적으로 어떠한 상태도 가지지 않음
    - 입축력 결과만 중요
  • 추가로 부수효과가 없다는 것은
    - 변수의 변형이 없음
    - 어떤 함수에 특정 값을 입력하면 그에 따른 출력이 발생. 같은 값을 입력하면 항상 그에 따른 출력도 같다.
    - 콘솔 또는 어떤 디바이스에도 출력하지 않는다.
    - 파일, 데이터베이스, 네트워크 어디에도 데이터를 쓰지 않는다.
    - 예외가 발생하지 않는다.

함수형 프로그래밍 원칙

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

위의 두가지는 같은 소리이다.

입출력이 순수하다는 것은 반드시 하나 이상의 인자를 받고, 받은 인자를 처리하여 반드시 결과물을 돌려주어야 한다는 것이다.

인자를 제외한 다른 변수는 사용하면 안된다. 받은 인자만으로 결과물을 내어야한다. 이러한 함수를 순수함수라고 부른다.

자바스크립트는 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)

위의 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);

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

참고 출처

profile
프론트엔드 주니어 개발자 🚀

0개의 댓글