왜 함수형 프로그래밍을 해야하는가?
함수형 프로그래밍(FP)은 결코 새로운 개념이 아닙니다. 프로그래밍의 거의 모든 역사에 걸쳐 있었습니다.
하지만, 원래는 주류가 아니었던 FP 가 현재는 언어 수준 뿐만 아니라 정말 많은 부분에서 그에 대한 관심이 커지고 있습니다!
그래서 왜 이 함수형 프로그래밍을 해야하는지 아래 두 예제를 보면서 살펴보겠습니다.
두 예제는 정확히 동일한 outcome 인 42 를 반환합니다.
첫번째 예제 )
var numbers = [4,10,0,27,42,17,15,-6,58];
var faves = [];
var magicNumber = 0;
pickFavoriteNumbers();
calculateMagicNumber();
outputMsg(); // The magic number is: 42
// ***************
function calculateMagicNumber() {
for (let fave of faves) {
magicNumber = magicNumber + fave;
}
}
function pickFavoriteNumbers() {
for (let num of numbers) {
if (num >= 10 && num <= 20) {
faves.push( num );
}
}
}
function outputMsg() {
var msg = `The magic number is: ${magicNumber}`;
console.log( msg );
두번째 예제 )
var sumOnlyFavorites = FP.compose( [
FP.filterReducer( FP.gte( 10 ) ),
FP.filterReducer( FP.lte( 20 ) )
] )( sum );
var printMagicNumber = FP.pipe( [
FP.reduce( sumOnlyFavorites, 0 ),
constructMsg,
console.log
] );
var numbers = [4,10,0,27,42,17,15,-6,58];
printMagicNumber( numbers ); // The magic number is: 42
// ***************
function sum(x,y) { return x + y; }
function constructMsg(v) { return `The magic number is: ${v}`; }
먼저 세 가지 다른 함수의 조합인 sumOnlyFavorites(..)라는 함수를 생성합니다. 그 이후, 두 개의 필터를 결합합니다. 하나는 값이 10보다 크거나 같은지 확인하고 다른 하나는 20보다 작거나 같은지 확인합니다. 그런 다음 traducer composition 자리에 sum(..) 리듀서를 포함합니다. 결과 sumOnlyFavorites(..) 함수는 값이 두 필터를 모두 통과하는지 확인하는 리듀서이며, 그렇다면 value 를 더해줍니다.
그런 다음 방금 정의한 sumOnlyFavorites(..) 리듀서를 사용하여 먼저 숫자 목록을 줄이는 printMagicNumber(..)라는 또 다른 함수를 만들어 선호 검사를 통과한 숫자만 합산합니다. 그런 다음 printMagicNumber(..)는 최종 합산의 값을 constructMsg 을 통해 string 으로 변환해여 출력해줍니다.
이 두 예제를 보면서 첫번째 예제와 두번째 예제가 아직 나은점이 뭔지 모르겠다면 괜찮습니다!
같이 알아봅시다.!
가독성 측면에서
그래서 왜 functional programming 이 중요할까요? 이것에 대답할려면 우리는 프로그래밍 자체가 왜 중요한지에 대해서 좀 더 넓은 관점에서 봐야합니다. 저는 코드가 컴퓨터를 위한 일련의 단순한 명령 셋이라고 생각하지 않습니다.
사실 코드에서 가장 중요한 것은 사람들 간의 커뮤니케이션 할 때의 수단으로 쓰이는 것입니다.
개발자들은 유지보수하는데 시간의 70%를 단지 읽고 이해하는데 쓰는 것으로 알려진것처럼 코드가 가독성이 좋아야하는 것은 정말 중요합니다. FP는 가독성을 높이는데 도움을 줄 수 있습니다.
Imperative programming ( 명령형 프로그래밍 )
- 무엇을 어떻게 할 것인가
- 프로그램의 state 가 변하는 statement 를 선언하는 프로그램의 패러다임
- e.g) 친구 차가 고장났다면 친구 아빠한테 전화해서 어떻게 차를 고쳐주어야하는지 스텝별로 말해주는 것
Declarative programming / ( 선언형 프로그래밍 ) / 함수형 프로그래밍
- 무엇을 할 것인가
- state 가 어떤식으로 변하는지 설명없이 계산 로직을 표현하는 것. 결과에 집중!
- e.g) 친구 차가 고장났다면 친구에서 차 고쳐줘~ 라고 말해주기만 한다. 안에 내부 과정은 친구한테 알아서 해 라고 하는 것.
이 장의 앞부분에 나온 두 개의 코드 조각을 다시 살펴보겠습니다.
첫번째 예제
첫 번째 예제는 필수적이며 거의 전적으로 작업 수행 방법에 중점을 둡니다. if 문, for 루프, 임시 변수, 재할당, 값 돌연변이, 부작용이 있는 함수 호출, 함수 간의 암시적 데이터 흐름으로 가득 차 있습니다. 숫자가 어떻게 흐르고 최종 상태로 변경되는지 보기 위해 논리를 추적할 수 있지만 전혀 명확하거나 간단하지 않습니다.
두번째 예제
두 번째 예제는 더 선언적으로 쓰였습니다. 앞서 언급한 명령형보다 훨씬 간단하게 명시적인 조건, 루프, 부작용, 재할당 또는 돌연변이가 없습니다. 대신 필터링, 축소, 변환 및 composition과 같은 잘 알려져 있고(어쨌든 FP 세계에!) 신뢰할 수 있는 패턴을 사용합니다. 낮은 수준의 방법에서 높은 수준의 결과로 이동합니다. 숫자를 테스트하기 위해 if 문을 엉망으로 만드는 대신 gte(..)(크거나 같음)와 같은 잘 알려진 FP 유틸리티에 위임한 다음 결합해서 필터링하여 처리합니다. 훨씬 더 명확하네요!
또한 데이터 흐름이 명확히 보입니다. 처음에, 숫자 리스트는 printMagicNumber(..) 함수에 들어갑니다. 한 번에 하나씩 해당 숫자가 sumOnlyFavorites(..)에 의해 처리되어 합계가 생성됩니다. 이 합계는 configureMsg(..)를 사용하여 메시지 문자열로 변환됩니다. 메시지 문자열은 console.log(..)를 사용하여 콘솔에 인쇄됩니다.
밸런스를 찾는 법
여전히 이 접근 방식이 복잡하고 명령형 스니펫이 더 이해하기 쉽다고 느낄 수 있습니다. 당신은 그것에 훨씬 더 익숙하기 때문입니다. 프로그래밍을 오랫동안 해 왔다면 "YAGNI"라는 문구를 전에 들어본 적이 있을 것입니. "You Ain't Gonna Need It". 이 원칙은 주로 극단적인 프로그래밍에서 비롯되며 필요하기 전에 기능을 구축하는 데 따르는 높은 위험과 비용을 강조합니다.
함수형 프로그래밍을 적용할 수 있다고 해서 반드시 적용해야 하는 것은 아닙니다. 일반적으로 코딩할 때 균형을 찾고 FP 개념을 적용할 때는 보수적인 태도를 취하는 것이 좋습니다. 특정 패턴이나 추상화가 코드의 해당 부분을 더 읽기 쉽게 하는 데 도움이 되는지에 대해서 면밀히 살펴보고 YAGNI 원칙에 따라서 결정해야 합니다. 한번도 사용하지 않은 확장성 포인트만 생각하게 되면 오히려 전체 프로그래밍에 대해서 방해가 될 수 있기 때문에 적절한 밸런스를 통해서 함수형 프로그래밍을 적용하는 것이 필요합니다.
참고
'이유's Programming > JavaScript' 카테고리의 다른 글
Redux 에서 Mobx 상태관리 도입기 - 참고 (0) | 2021.03.23 |
---|---|
[ 구글 채널 ] Scheduling Tasks - HTTP 203 (1) | 2021.03.02 |
[ React -1 ] React.memo 를 사용하여 컴포넌트 성능 최적화하기 . / React.memo 사용할 때 그리고 사용하지 않을 때 팁 정리 (0) | 2021.01.26 |
자바스크립트 MAP - array 는 배열로 관리하기. / array 를 key 로 접근 (0) | 2021.01.23 |
5강 Class (0) | 2020.07.11 |