함수형 프로그래밍 언어는 커링이라는 기법을 가지고 있습니다. 논리학자 헤스켈 브룩 커리의 이름에서 유래했고 여러개의 인자를 받는 함수를 나머지 인자를 받는 함수로 변환하는 메커니즘입니다.  (위키피디아) 쉽게 말해 두 개의 인자를 받는 함수를 하나의 인자를 받는 함수로 변환하는 기법이라고 설명 드릴 수 있습니다.
커링을 이해 하기 위해서 스칼라 코드를 보겠습니다.

// 선언
def mulOneAtATime(x: Int) = (y: Int) => x * y
// 실행
mulOneAtATime(6)(7) // 42

대충 감이 오시죠? 그러면 Javascript는 커링을 어떻게 표현할까요?
다음은 Javascript에서 커링을 표현하는 가장 잘 알려진 방법입니다.

// 선언
function mulOneAtATime(x) {
    return function(y) {
        return x * y;
    };
}
// 실행
mulOneAtATime(6)(7); // 42

제대로 동작하는 것 같지만 커링과 거리가 멉니다.
위에서 커링은 인자 두 개를 받는 함수를 인자 하나를 받는 함수로 바꾸는 메커니즘이라고 말씀드렸습니다. 하지만 위 코드는 애초부터 1개의 전달인자를 요구 합니다. 2개의 전달인자를 전달하여 사용할 수 없습니다.
이 문제를 해결하기 위해 헬퍼 함수를 작성하여 커링을 표현합니다.

// 헬퍼 함수.
var curry = function(fn /*, ... */){
    var curryArgs = Array.prototype.slice.call( arguments, 1 );
    return function( /* ... */ ) {
        var newArgs = Array.prototype.slice.call( arguments, 0 ),
            mergedArgs = curryArgs.concat( newArgs );
        return fn.apply( this, mergedArgs );
    }
};
// 선언
function mul(x, y) {
    return x * y;
}
// 실행
mul(6, 7); // 42
curry(mul, 6)(7); // 42

별도의 헬퍼 함수를 구현하여 억지로 커링을 흉내내고 있습니다. 복잡해 보이고 세련되지 못하네요.
대부분 Function.prototype.bind 메소드는 context를 bind 하는 용도로 사용합니다만 이를 이용해 커링을 거의 완벽하게 표현할 수 있습니다.

// 선언
function mul(x, y) {
    return x * y;
}
var mulOneAtATime = mul.bind(null, 6);
// 실행
mul(6, 7); // 42
mul.bind(null, 6)(7); // 42
mulOneAtATime(7); // 42

따로 헬퍼 함수를 작성할 필요도 없을 뿐더러 코드도 읽기 쉬워졌습니다.
그럼 커링을 실무에서 어떻게 쓸 수 있을까요? 음… 이렇게 써볼 수 있지 않을까요?

// 선언
function template(name, money){
    return '<h1>'+ name +'</h1><span>'+ money +' </span>';
}
var tmplGildong = template.bind(null, '홍길동');
var tmplCheolsu = template.bind(null, '김철수');
// 실행
template('김병수', 30); // <h1>김병수</h1><span>30원</span>
tmplGildong(10); // <h1>홍길동</h1><span>10원</span>
tmplGildong(100); // <h1>홍길동</h1><span>100원</span>
tmplGildong(130); // <h1>홍길동</h1><span>130원</span>
tmplCheolsu(500); // <h1>김철수</h1><span>500원</span>
tmplCheolsu(1000); // <h1>김철수</h1><span>1000원</span>

이 외에도 메소드 오버로딩이 안되는 Javascript에서 커링으로 우아한 코드를 생산할 수 있을 것 같습니다. 그렇지만 가독성이나 흐름을 크게 해칠 우려가 있기 때문에 조심히 다뤄야 합니다.
여기까지 Function.prototype.bind 메소드를 사용해서 커링을 표현해봤습니다.
참고 자료 :

카테고리: Research

UYEONG

사케와 힙합을 즐길 줄 아는 프론트엔드 개발자입니다.

1개의 댓글

CHoi · 2020년 2월 21일 6:02 오후

부럽습니다. 저도 취미생활있으면서 코딩도잘하고싶네요.

답글 남기기

아바타 플레이스홀더

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다