이번 글에서는 함수형 프로그래밍 패러다임의 기초가 되는 currying
테크닉에 관해 알아보도록 할게요.
함수형 프로그래밍에서 currying
은 다음과 같습니다.
어떤 함수의 실행을 부분부분으로 쪼개서 실행할 수 있도록 만들어주는 테크닉.
코드로 표현해보자면 다음과 같은 모습이죠.
sum(1, 2, 3) // 일반 함수
sum(1)(2)(3) // currying 테크닉이 적용된 함수
즉, 함수에 인자를 감질맛나게 하나씩 넘겨주면서 모든 인자가 다 들어온 시점에서야 최종 계산이 이루어지는 방식입니다.
curring 을 해주는 curry
함수의 인자와 반환값부터 생각해보겠습니다.
인자로는 함수를 받고, 반환값은 함수 입니다.
이제 curry
함수 구현에 필요한 내용을 정리해볼게요.
curry
함수 정의
- 인자로는 함수를 하나 받으며, 새로운 함수를 반환한다.
- 반환되는 함수는 인자를 여러개 받을 수 있다.
- 반환되는 함수는 2가지 경우를 분기하여 처리한다.
- 전달 받은 인자의 갯수가
curry
함수의 인자로 전달된 함수 인자 개수 이상인 경우 -> 즉시 실행- 전달 받은 인자의 갯수가
curry
함수의 인자로 전달된 함수 인자 개수 미만인 경우 -> 함수 평가를 지연시킴.
한 번 코드로 구현하며 더 자세히 살펴보겠습니다.
우선 curry
함수의 뼈대만 다음과 같이 잡습니다.
반환되는 함수 curried
는 인자를 여러개 받을 수 있게 ...
연산자를 사용해주었습니다.
function curry(func) {
return function curried(...args) {
}
}
이제 curried
함수 내부를 구현할 차례인데요,
curried
함수에 전달된 인자의 개수가 func
함수 인자 개수 이상인 경우를 먼저 살펴보죠.
function curry(func) {
return function curried(...args) {
if (args.length >= func.length) {
// 즉시 실행
return func.apply(this, args)
}
}
}
다음으로 curried
함수에 전달된 인자의 갯수가 func
함수 인자 개수 미만인 경우 입니다.
function curry(func) {
return function curried(...args) {
if (args.length >= func.length) { // Function.prototype.length => 함수의 인자 개수를 반환하는 property
// 즉시 실행
return func.apply(this, args)
} else {
// 새로운 함수를 반환함으로써 함수의 실행을 지연시키고,
// 추가로 받은 인자 개수만큼 인자 배열에 붙인다.
return function (...args2) { // 이 익명 함수는 클로져(Closure)이다.
return curried.apply(this, args.concat(args2))
}
}
}
}
클로져까지 나와서 살짝 머리가 복잡할 수 있습니다.
천천히 흐름을 따라가려 해보시고, 다음 섹션에서 함수를 테스트하며 설명드릴 예시를 보시면 이해가 한층 수월하실거에요.
숫자를 3개 받아서 모두 더한 값을 반환하는 sum
이라는 함수를 currying 하는 간단한 예제를 보며 curry
함수의 동작 원리를 좀 더 살펴보겠습니다.
const sum = (a, b, c) => a + b + c
const curriedSum = curry(sum) // function curried(...args)
console.log(curriedSum(1)) // function (...args2) { return curried.apply(this, [1].concat(args2)) }
console.log(curriedSum(1)(2)) // function (...args2) { return curried.apply(this, [1, 2].concat(args2)) }
console.log(curriedSum(1)(2)(3)) // curried.apply(this, [1, 2].concat(3)) => sum.apply(this, [1, 2, 3]) 이므로 "6"
함수를 값으로 다루는 것 + 클로져 패턴이 조합되어서 처음에는 생소하기 때문에 어렵게 느껴질 수 있습니다!
반복적으로 보시면서 익숙해지게되면 처음보단 많이 쉽게 느껴지실 거에요.