Functional Programming 시각적으로 이해하기
각 개념의 아키텍처를 애니메이션 다이어그램으로 살펴보세요. 카드를 클릭하면 더 깊은 내용을 확인할 수 있습니다.
순수 함수
입력만으로 결과가 결정되는 함수
순수 함수는 주어진 입력만으로 결과가 결정되고, 외부 세계에 어떤 흔적도 남기지 않는 함수입니다. 같은 인자를 두 번 넣으면 반드시 같은 값을 돌려주고, 전역 변수나 파일, 네트워크 같은 외부 상태를 읽거나 바꾸지 않습니다. 함수형 프로그래밍에서 계산 로직을 가장 작게 믿을 수 있는 단위로 만들 때 자주 기준이 되는 개념입니다. 순수 함수가 많을수록 코드의 동작을 입력과 출력만으로 설명하고 추론하기 쉬워집니다.
불변성
값을 바꾸지 않고 새 값을 만드는 원칙
불변성은 한 번 만든 값을 나중에 바꾸지 않는 원칙입니다. 값을 수정하고 싶을 때는 기존 값을 변형하는 대신 새 값을 만들어 반환합니다. 원본이 그대로 유지되므로 같은 데이터를 여러 곳에서 공유해도 서로 영향을 주지 않고, 어떤 시점에 어떤 상태였는지 추적하기 쉬워집니다. 순수 함수가 지키기 쉬워지는 기반 조건이기도 합니다.
일급 함수
함수를 값처럼 다루는 언어의 성질
일급 함수는 언어가 함수를 다른 값과 똑같이 취급한다는 성질입니다. 숫자나 문자열처럼 함수를 변수에 담고, 인자로 넘기고, 반환 값으로 돌려받고, 배열이나 객체에 넣을 수 있습니다. 이것 자체는 함수 정의 방식이 아니라 '함수가 값이다'라는 언어 차원의 약속입니다. 이 약속이 있어야 고차 함수, 콜백, 함수 합성 같은 함수형 패턴이 전부 성립합니다.
고차 함수
함수를 받거나 돌려주는 함수
고차 함수는 함수를 인자로 받거나 결과로 반환하는 함수입니다. 일반 함수는 숫자나 문자열 같은 값을 입력받아 값을 돌려주지만, 고차 함수는 동작 자체를 입력받거나 새 동작을 만들어 돌려줍니다. 덕분에 '어떤 일을 할지'의 뼈대는 공통으로 두고, 그 안에서 실제로 수행할 세부 동작만 바깥에서 주입할 수 있습니다.
클로저
함수가 바깥 스코프의 값을 기억하는 구조
클로저는 함수가 만들어질 당시의 바깥 스코프를 함께 기억하는 구조입니다. 함수 안에서 바깥 변수를 참조하면, 바깥 함수가 이미 끝나 사라진 뒤에도 안쪽 함수는 그 변수를 계속 쓸 수 있습니다. '함수 + 그 함수가 자라난 환경'이 한 덩어리로 묶여 다니는 셈입니다. 자바스크립트의 스코프와 함수 반환 구조에서 자연스럽게 생기는 개념이라 별도의 문법이 없는 언어도 많습니다.
함수 합성
작은 함수를 이어 붙여 큰 함수 만들기
함수 합성은 여러 개의 작은 함수를 이어 붙여 하나의 함수로 만드는 기법입니다. 첫 함수의 출력이 다음 함수의 입력이 되고, 다음 함수의 출력이 그 다음으로 흘러가면서 데이터가 파이프라인처럼 이동합니다. 각 단계를 작은 함수로 쪼개 두면 재사용과 테스트가 쉬워지고, 합성된 결과 함수는 '이 단계를 이 순서로 적용한다'는 의도를 코드에 그대로 드러냅니다.
map/filter/reduce
컬렉션을 변환하는 세 가지 기본 도구
map, filter, reduce는 배열(또는 컬렉션)을 다루는 세 가지 기본 도구입니다. map은 각 원소를 변환하고, filter는 조건에 맞는 원소만 남기고, reduce는 원소를 하나의 값으로 모읍니다. 세 함수 모두 원본을 바꾸지 않고 새로운 값을 만들어 반환한다는 공통점이 있으며, 고차 함수의 가장 대표적인 활용 사례입니다. 함수형 스타일로 데이터를 다루는 실무 코드의 대부분이 이 세 가지 조합으로 이뤄집니다.
재귀
함수가 자기 자신을 호출해 반복을 표현
재귀는 함수가 자기 자신을 호출해 반복 작업을 표현하는 방식입니다. 큰 문제를 같은 구조의 더 작은 문제로 쪼개고, 충분히 작아졌을 때 직접 답을 내는 종료 조건을 두어 호출 사슬을 끝냅니다. 반복문이 '몇 번 도는가'에 집중한다면, 재귀는 '문제를 어떻게 쪼개는가'에 집중합니다. 트리처럼 깊이를 미리 알 수 없는 자료구조를 다룰 때 특히 자연스럽습니다.