-
Initial commit - FPFP 2020. 7. 7. 02:19반응형
애플리케이션 설계 요소
- 확장성: 추가 기능을 지원하기 위해 계속 코드 리팩토링해야 하는가?
- 모듈화 용이성: 파일 하나를 고치면 다른 파일도 영향을 받는가?
- 재사용성: 중복이 많은가?
- 테스트성: 함수를 단위 테스트하기 어려운가?
- 헤아리기 쉬움: 체계도 없고 따라가기 어려운 코드인가?
함수형 프로그래밍(Functional Programming) 이란?
- 함수 사용을 강조하는 소프트웨어 개발 스타일
- 진짜 목표는 애플리케이션의 부수효과(side effect) 를 방지하고 상태 변이(mutation of state) 를 감소하기 위해 데이터의 제어 흐름과 연상을 추상화(abstract) 하는 것
어려울땐 예제로 보자
document.querySelector('#msg').innerHTML = '<h1>Hello World</h1>';
위 코드를 함수로 바꿔서 재사용성을 높여보자
function printMessage(elementId, format, message) { document.querySelector(`#${elementId}`).innerHTML = `<${format}>${message}</${format}>`; } printMessage('msg', 'h1', 'Hello World');
괜찮아 진건가? 재사용성을 극대화 하기 위해 HTML이 아닌 파일이나 DB에 쓴다면 어떻게 바꿀 수 있을까?
그렇다. 여기에서부터 함수를 매개변수로 넘긴다는 발상의 전환이 필요하다.
var printMessage = run(addToDom('msg'), h1, echo); printMessage('Hello World');
갑자기 너무 나갔네?위 코드는
run
이라는 함수에addToDom('msg')
,h1
,echo
라는 함수를 파라미터로 넘긴 코드다.
실행 순서는run
->echo
->h1
->addToDom('msg')
순으로 실행되며, 새로운 함수를 반환한다.한번
console
로 확장해보자var printMessage = run(console.log, repeat(2), h2, echo); printMessage('Get Functional')
벌써 FP의 꽃인 합성을 배웠다.
위 코드의 합성 정리
- 더 작은 조각들로 프로그램을 나눈 후
- 전체적으로 더 헤아리기 쉬운 형태의 프로그램으로 다시 조합하는 과정
- 함수형 프로그램의 기본 원리
근데 솔직히... 영어권이나 영어에 능통한 고수들이나 헤아리기 쉽지 나같은 영알못은 처음엔 더 어렵더라...
그럼 어째? 더 열심히 공부해야지! :p자 그럼 FP를 더 이해하기 위해 그 이면에 깔려 있는 다음 기본 개념들을 알아보자
선언적 프로그래밍
프로그램의 서술부(description)와 평가부(evaluation)를 분리하여 제어 흐름이나 상태 변화를 특정하지 않고도 프로그램 로직이 무엇인지를 표현식(expression)으로 나타냄
순수함수
주어진 입력에만 의존하며 외부 상태와 무관하게 작동하므로 함수 스코프 밖으로 어떠한 변경도 일으키지 않음
참조 투명성
순수함수를 정의하는 좀 더 공식적인 방법으로 어떤 함수가 동일한 입력을 받았을 때 동일한 결과를 내는 것
불변성
함수 또는 변수가 선언된 뒤 다른 값으로 바뀌지 않는 것
그럼 함수형 프로그래밍을 사용하면 뭐가 좋은가?
복잡한 작업을 분해하도록 유도
함수형 프로그래밍은 사실 코드들을 잘게 잘게 쪼개서 단일 함수로 만들고
그 함수들을 조합해서 커다란 기능을 구현하는 방식이다.이렇게 하면 뭐가 좋은가?
바로 모듈성 이 향상된다.
모듈성이 향상되면 뭐가 좋은가?
바로 재사용성 과 테스트 용이성 이 높아져서 신뢰성 은 2+1으로 따라온다.
할만하지 않은가?
또한 잘게 잘게 쪼갠 함수들을 합성해서 커다란 함수를 만들 때
영작 을 잘 한다면 굉장히 읽기 좋은 코드를 만들 수 있다.
영작을 잘 한다 면 말이다.
후후... 왜 슬프지?데이터를 매끄럽게 체이닝하여 처리
체인도 합성처럼 코드를 간결 명료하게 작성할 수 있다.
예제를 한번 보자.
enrolled
값이 2 이상인 친구들의 평균을 구하는 함수다.enrolled
는 영어사전을 찾아보길 바란다.영어공부 해야지?const enrollment = [ {enrolled: 2, grade: 100}, {enrolled: 2, grade: 80}, {enrolled: 1, grade: 89} ]; let totalGrades = 0; let totalStudentsFound = 0; for (let i = 0; i < enrollment.length; i++) { const student = enrollment[i]; if (student !== null) { if (student.enrolled > 1) { totalGrades += student.grade; totalStudentsFound++; } } } const average = totalGrades / totalStudentsFound; // 90
이 블로그 포스팅을 본 후로 위와 같은 코드 대신 아래와 같은 코드를 짜도록 노력해보자.
_.chain(enrollment) .filter(student => student.enrolled > 1) .pluck('grade') .average() .value(); // 90
어떤가? 각 함수에서는 본인의 관심사만 처리하도록 아름답게 변했다.
요 체인의 또다른 장점 중 하나는 느긋한(?) 게으른(?) 평가가 가능하다.
물론 그냥 쓸 수는 없고, 위의 함수에서 사용된filter
,pluck
과 같은 고계함수들을 반복기 로 구현하면 가능하다.
로대시에서 기본적으로 적용이 되어 있는지는 모르겠다. 이부분은 찾아보고 업데이트 하도록 하겠다.복잡한 비동기 애플리케이션에서도 신속하게 반응
제목이 이해하기 좀 구리긴 한데 사실 리액티브 프로그래밍에 대한 설명이다.
리액티브 프로그래밍을 사용하면 굉장히 높은 수준의 추상화가 가능해서
비동기 코드와 이벤트 중심 코드의 복잡도를 현저하게 주일 수 있고
덕분에 비지니스 로직에만 전념할 수 있도록 도와준다.근데 갑자기 왜 뜬금없이 리액티브 프로그래밍이 튀어나오는가?
함수형으로 사고하다 보면 결국 함수형 리액티브 프로그래밍이라는 기가막힌 아키텍처에 눈을 뜨게 된다고 한다.
그래서 이곳에서 미리 맛만 살짝 보여주려고 한다.코드로 맛을 보자. 무슨 맛인지.
학생의
SSN(미쿡인의 주민등록번호)
을 읽고 올바른지 검증하는 함수다.var valid = false; var elem = document.querySelector('#student-ssn'); elem.onkeyup = function(event) { var val = elem.value; if (val !== null && val.length !== 0) { val = val.replace(/^\s*|\s*$|\-/g, ''); if (val.length === 9) { console.log(`올바른 SSN: ${val}!`); valid = true } } else { console.log(`잘못된 SSN: ${val}!`); } }
이 함수를 RxJS를 사용해서 바꿔보자
Rx.Observable.fromEvent(document.querySelector('#student-ssn'), 'keyup') .pluck('srcElement', 'value') .map(ssn => ssn.replace(/^\s*|\s*$|\-/g, '')) .filter(ssn => ssn !== null && ssn.length === 9) .subscribe(validSsn => console.log(`올바른 SSN: ${validSsn}!`));
굉장하다... 어서... 어서 RxJS 배우러... 가자...
마무리
책에서는 함수형 프로그래밍을 다음과 같이 정의내리고 있다.
함수형 프로그래밍은
외부에서 관찰 가능한 부수 효과가 제거된
불변 프로그램을 작성하기 위해
순수함수를
선언적으로 평가하는 것입니다그렇다고 함수형 프로그래밍이 객체지향 프로그래밍을 완전히 대체하는 건 아니다.
나름대로 두 패러다임 각각의 멋과 맛이 있다.
이걸 잘 조합해서 더 멋있고 맛있게 사용하는 날이 오길 :)출처: 함수형 자바스크립트
반응형'FP' 카테고리의 다른 글
Function (0) 2020.07.12 How to make the Object as immutable in JS (0) 2020.07.09 FP vs OOP (0) 2020.07.08