FP - Pipe
Pipe 의 사전적 의미
배관들은 A 에서 B 라는 지점으로 자원을 보내는 용도로 많이 사용된다.
단순히 터널과 같은 공간의 개념이라고 생각하면 된다.
파이프 함수는 실제 현실에서의 파이프(배관)에서 아이디어를 가져왔다고 봐도 좋겠다
FP - Pipe
파이프는 단방향 통신을 위한 용도로 사용된다.
하나의 파이프는 그 이전 파이프에서 전달된 결과를 파라미터로 삼아 또 다른 결과를 내놓는다.
파이프를 이해하기위한 선행 학습
순수함수
- 같은 입력 값에선 같은 반환 값을 보장한다.
- 함수 외부 스코프의 그 어떠한 변수의 값도 바꾸지 않는다.
그런데 왜 순수 함수가 파이프에서 중요한가?
위에서 말한 것처럼, 한 파이프가 반환하는 값은 그 다음 파이프의 입력 값으로 전달된다.
그런데 파이프가 상황에 따라서 다른 값을 반환하면 그 다음 파이프의 입장에서는 상황에 따라 바뀔 수 있는 불안정한 값이 입력 값으로 들어오는 셈이므로 결국 반환 값 역시 불안정할 수 밖에 없다.
Pipe 구현
pipe 함수를 구현해보자. reduce를 이용하여 순서대로 함수들을 수행해가면서 return 값을 다음 함수로 넘겨준다.
reduce 가 하는 일은 배열을 순회하면서 궁극적인 하나의 반환 값을 만들어낸다.
const pipe = (funcs, v) => {
return funcs.reduce((res, func) => {
return func(res);
}, v);
};
const addFive = v => v + 5;
const identity = v => v;console.log(pipe([
addFive,
identity
], 5));
// 10
잘 돌아간다. 그렇지만 사실 문제가 하나 더 있다.
여기서 파이프는 배열밖에 받지 못한다.
그래서 아래처럼 단일 함수로는 사용할 수 없다.
pipe(addFive, 5);
// ~~~
// Uncaught TypeEror: funcs.reduce is not a function
파이프가 단일 함수 역시도 인자로 받을 수 있게 수정되면 더 좋을 것 같다.
이 단계에서는 Rest 파라미터를 사용한다.
Rest 파라미터는 함수가 타입 제한 없이 모든 파라미터들을 하나의 배열에 담아 받는 형태의 파라미터를 의미한다.
// Rest 파라미터는 반드시 마지막 순서에 적어야 한다 !!
//Rest 파라미터는 이름 그대로 먼저 선언된 파라미터에 할당된 인수를 제외한 나머지 인수들이 모두 배열에 담겨 할당된다.
//따라서 Rest 파라미터는 반드시 마지막 파라미터이어야 한다.
const pipe = (v, ...funcs) => {
return funcs.reduce((res, func) => {
return func(res);
}, v);
};
const subtract = v => v - 5;
console.log(pipe(10, subtract)); // 5
여기서는 함수와 값의 전달 위치를 변경했다.
Rest 파라미터를 사용하면서 함수를 넘기는 순서를 바꿨으므로 값의 전달 위치 역시 바뀌어야 했다
위에 방법도 있지만 클로져를 이용한 방법도 있다.
그래서, 클로져를 이용하면 파이프는 다음과 같이 변모한다.
const pipe = (...funcs) => v => {
return funcs.reduce((res, func) => {
return func(res);
}, v);
};
pipe(add)(5) // 10
이제 파이프는 v 라는 값을 받는 또 다른 함수를 반환하는 형태로 바뀌었다.
새롭게 반환된 함수가 v 를 받을 때 까지 파이프는 reduce 를 실행하지 않는다.
이 기법은 “게으른 값의 평가” 를 가능하게 한다.
마지막 단계로 제대로 동작하는지 확인하자.
테스트
const minusFive = v => v - 5;
const addFour = v => v + 4;
const multiplyByTen = v => v * 10;
const identity = v => v;const res = pipe(
minusFive,
addFour,
multiplyByTen,
Math.abs,
identity
)(0);
console.log(res); // 10. 잘 작동한다 !
정리
파이프는 함수형 프로그래밍에서 매우 유용하게 사용할 수 있는 기법이다.
함수의 복잡도를 줄이고 가독성을 증가시켜준다.
다만 한 가지 기억해둘 점은 파이프에 사용되는 모든 함수들은 순수 함수인 상태로 만들어져야 한다는 점이 있다.
-- 참조
함수형 프로그래밍 — Pipe
파이프란 무엇이고 어떻게 사용하는가?
medium.com