본문 바로가기

Programming/Javascript

14. Javascript 함수형 프로그래밍(4) - 팩토리얼 구현하기

javascript logo image

 

이번에는 팩토리얼을 함수형 프로그래밍을 통해 구현하는 방법을 살펴보도록 하겠습니다. 우선은, 우리가 익히 알고 있는 명령형 프로그래밍 방식으로 함수 factorial을 구현해 보겠습니다. 

 

function factorial(num) {
    var val = 1;
    for(var i = 1; i <= num; i++) {
        val *= i;
    }
    return val;
}

console.log(factorial(5));

 

위의 코드를 재귀함수 형태로도 구현해 보면, 아래와 같이 구현할 수 있습니다.

 

function factorial(num) {
    if(num == 0) {
        return 1;
    } else {
        return num * factorial(num-1);
    }
}

console.log(factorial(5));

 

이제 함수형 프로그래밍 방식을 통해 팩토리얼을 구현해 볼 텐데, 여기서는 구현에 있어서 전제 조건이 있습니다. 우선, 클로저를 사용하며 이를 통해 특정 값을 저장해 두고 계속 사용하는 '캐시'를 생성하는 것을 전제로 합니다. 그리고, 팩토리얼에서 이 캐시가 활용되는 이유는 반복 동작을 최소화 하여 성능을 높이기 위함입니다. 

 

즉, 10!을 연산했을 때 1부터 10까지의 곱셈을 수행합니다. 그런데 20!을 연산하게 되면 사실 1부터 10까지의 곱셈을 다시 수행하게 되므로 이를 재활용하기 위해서 기존의 수행 값을 저장해 두고 재활용하려고 하는 것입니다. 

 

var fact = function() {
    var cache = {'0' : 1};
    var func = function(n) {
        var result = 0;

        if(typeof(cache[n]) === 'number'){
            result = cache[n];
        } else {
            result = cache[n] = n * func(n-1);
        }
        return result;
    }

    return func;
}();

console.log(fact(3));
console.log(fact(5));

 

위 예제에서는 클로저를 활용하고 있습니다. 여기서 최초 선언한 함수 fact는 cache에 접근할 수 있는 클로저를 반환 받아 사용하게 됩니다. 그리고 해당 cache에는 기존 팩토리얼 연산 값이 저장되어 재활용이 가능한 구조로 구현되어 있습니다. 이러한 방식을 메모이제이션(memoization) 패턴이라고 하며, 계산 결과를 저장해 놓고 이후 다시 계산하지 않고 재활용하는 방법으로 정의하고 있습니다. 계산된 결과 값을 함수 프로퍼티값으로 담아 놓고 나중에 다시 쓰는 형태인데, 이는 뒤이어 살펴볼 몇 가지 함수형 프로그래밍 구현 예제에서도 계속 활용할 예정입니다. 

 

재귀함수 호출과 클로저 개념이 다시 튀어나와 다소 어렵게 느껴질 수 있지만, 우선은 반복하여 이러한 방법에 익숙해지는 것을 목표로 하여 연습해보도록 합시다.