함수형 자바스크립트의 메소드 활용(2)

두고두고 쓸거란 말이다! Currying이란 녀석의 사용법

이전 글의 다음 문제들로 이어진다.
‘바인드 없는 부분 애플리케이션', ‘바인드 있는 부분 애플리케이션’
다음과 같은 문제들을 풀 수 있을 것이다. 글을 작성하겠다. 꼬우

var add = function (a, b) {
return a + b;
}

var add_ten = curry(add, 10) => 두번째 인자는 10으로 고정

var fifteen = add_ten(5) => 15

위의 코드는 하나의 인자를 고정된 상태로 이루어져야한다.
어뜨케 하겠느냐? curry 함수를 만들어보아라.
아 그전에 currying를 설명하겠다.

커링(currying)이란 함수형 프로그래밍 기법 중 하나로 함수를 재사용하는데 유용하게 쓰일 수 있는 기법이다.

아래 링크 참조
https://medium.com/@jinro4/%EA%B0%9C%EB%B0%9C-currying-in-javascript-e7ccdd7862e0#.l4j875s5r

위의 링크의 정의가 쉽게 와 닿을 수 있는 것 같다.

커링은 함수의 조각들을 통해 새로운 함수를 생성하는 방법으로 초기 함수에 넘겨진 인자를 참조하는 새로운 함수를 생성하는 형태로 구현한다.

초기 함수에 넘겨진 인자를 참조..? 이걸 보고 하나가 떠올랐길 바란다.
그렇다! 클로져다. 필수템이다.
모른다면 알고 오길 바란다….ㅎㅎ 살짝만 맛보고 오길 바란다.

자 다시 본론으로!
curry 함수를 만들어보았는가?
아무것도 모르고 그냥 만들었을 때 난 이렇게 만들었다.

function curry(fn, n){
return function(num){
return fn(num, n);
}
}

위에서 말한 정의와 같이 curry함수를 통해 넘겨온 인자들을 참조하는 새로운 함수들이 생성된다. 
간단히 이것이 currying의 형태이다.
자 하나 더 보자! 커링은 재사용성에 유용한 기법이라고 했다.
위의 코드처럼 작성했는가?? 그럴거라고 생각하겠다..
하지만 개발자라면 ㅠㅠ 함수의 재사용성을 고려해야한다..
난 어려워죽겠다.. 너무 고려할 게 많다..
지금의 curry함수는 딱 저 기능 딱 저거밖에 할 수 없다.
하지만 add 함수에 3개의 인자 4개의 인자를 하고 싶다면 어떻게 할 것인가?
물론 인자를 그냥 늘려버리면 되겠지만….!
그것이 재사용성이라 할 수 있겠느냐?!(내가 할말은 아니지만..)

var curry = function (fn) {
var slice = [].slice,
args = slice.call(arguments, 1);
//var arg = Array.prototype.slice.call(arguments);
//var fn = arg.shift();
return function () {
return fn.apply(this, args.concat(slice.call(arguments)));
};
};

이렇게 코드를 작성했더니 재사용성이 확 높아졌다.
항상 고려하자 고려! 
위와 같은 형태로 ‘바인드 없는 부분 애플리케이션’ 문제를 풀면 되겠다.
join, shift, unshift 메소드를 알아두면 좋을 것이다.

조금 더 나아가 curring의 기반으로 한 bind 기능을 사용해보도록 하겠다!
일단 bind에 대해서 잠깐 소개하겠다.

지정된 함수에 대해 원본 함수와 동일한 본문을 갖는 바인딩된 함수를 만듭니다.바운드 함수에서 this 개체는 개체에 전달된 것으로 확인됩니다.바인딩된 함수에는 지정된 초기 매개 변수가 있습니다.

bind는 예제를 보는 게 제일 이해가 쉬울 것이다.

var person = {
name: 'Example Person',
greet: function (salutation, thing) {
return this.name + ' says: ' + salutation + ', ' + thing + '!';
}
};

var tom = {
name: 'Tom'
};

var tom_says_hi = person.greet.bind(tom, 'Hi');

console.log(tom_says_hi('Jim')); // Tom says: Hi, Jim!

위 코드는 person 객체의 greet 속성을 bind 시킨다.
bind를 통해 tom 객체를 참조하도록 하고, ‘Hi’를 인자로 보낸다.
tom_says_hi 객체의 this는 tom을 참조하기 때문에 name 속성은 Tom으로 출력되게 된다!
이것이 bind이다. bind의 용도를 이해하겠는가?!
그렇다면 이제 curring을 통해 bind의 기능을 활용해보자!

var curry_bind = function (fn, that) {
var slice = [].slice,
args = slice.call(arguments, 2);
return function () {
return fn.apply(that, args.concat(slice.call(arguments)));
};
};

위의 curry 함수와 거의 동일하다.
차이점은 slice 인자를 2를 줬다. 그 이유는 fn, that을 유지할려고!
fn는 사용할 함수이고 that은 참조할 놈이다. 아래의 코드를 보면 알 것이다.

var person = {
name: 'Example Person',
greet: function (salutation, thing) {
return this.name + ' says: ' + salutation + ', ' + thing + '!';
}
};

var tom = {
name: 'Tom'
};

var tom_says_sup = curry_bind(person.greet, tom, 'Sup');

console.log(tom_says_sup('dawg?')); => Tom says: Sup, dawg?!

어떤가? currying을 이용하여 bind의 기능까지 구현하였다.
놀라운가? 난 놀랍다……. 자바스크립트는 참 많은 것들이 있다..
그래서 어렵다… 그래서 재밌다…. 그래서 짜증난다…^^
여기까지… 이 녀석 때문에 늦게 자는군…

참조 : http://phuu.net/2012/11/16/useful-js-currying-and-bind.html

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.