함수형 프로그래밍
Functional Programming
순수 함수와 불변성을 강조하는 패러다임. 부수효과 최소화. Haskell, Scala, Rust에서 지원.
Functional Programming
순수 함수와 불변성을 강조하는 패러다임. 부수효과 최소화. Haskell, Scala, Rust에서 지원.
함수형 프로그래밍(Functional Programming)은 순수 함수와 불변 데이터를 중심으로 프로그램을 구성하는 패러다임입니다. 부수 효과(side effect)를 최소화하고, 함수를 일급 시민으로 취급하여 다른 함수에 전달하거나 반환할 수 있습니다. 이는 코드의 예측 가능성과 테스트 용이성을 높입니다.
순수 함수(Pure Function)는 동일한 입력에 항상 같은 출력을 반환하고, 외부 상태를 변경하지 않습니다. add(a, b) = a + b는 순수 함수이지만, 전역 변수를 수정하거나 I/O를 수행하는 함수는 순수하지 않습니다. 순수 함수는 테스트와 디버깅이 쉽고, 병렬 처리에 안전합니다.
불변성(Immutability)은 데이터를 변경하지 않고 새로운 데이터를 생성하는 원칙입니다. 객체를 수정하는 대신 복사본을 만들어 변경합니다. JavaScript의 spread 연산자, Python의 튜플, Rust의 기본 불변 변수 등이 불변성을 지원합니다.
고차 함수(Higher-Order Function)는 함수를 인자로 받거나 반환하는 함수입니다. map, filter, reduce가 대표적입니다. 커링(Currying)은 여러 인자를 받는 함수를 단일 인자 함수들의 체인으로 변환하는 기법으로, 함수 조합에 유용합니다.
// JavaScript 함수형 프로그래밍 예제
// 1. 순수 함수
const add = (a, b) => a + b;
const multiply = (a, b) => a * b;
// 2. 불변성 - 원본 수정 대신 새 객체 생성
const user = { name: 'Alice', age: 30 };
const updatedUser = { ...user, age: 31 }; // 불변 업데이트
// 3. 고차 함수 - map, filter, reduce
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2); // [2, 4, 6, 8, 10]
const evens = numbers.filter(n => n % 2 === 0); // [2, 4]
const sum = numbers.reduce((acc, n) => acc + n, 0); // 15
// 4. 함수 합성
const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x);
const addOne = x => x + 1;
const double = x => x * 2;
const addOneThenDouble = compose(double, addOne);
console.log(addOneThenDouble(5)); // 12
// 5. 커링
const curry = fn => a => b => fn(a, b);
const curriedAdd = curry(add);
const addFive = curriedAdd(5);
console.log(addFive(3)); // 8
// 6. 명령형 vs 함수형
// 명령형 (Imperative)
let total = 0;
for (let i = 0; i < numbers.length; i++) {
total += numbers[i];
}
// 함수형 (Declarative)
const totalFP = numbers.reduce((acc, n) => acc + n, 0);
시니어: 이 상태 관리 코드가 복잡해요. 불변 업데이트 패턴으로 리팩토링합시다.
주니어: 매번 복사하면 성능이 떨어지지 않나요?
시니어: Immer 같은 라이브러리를 쓰면 내부적으로 구조적 공유를 해서 효율적이에요. 게다가 디버깅할 때 상태 변화 추적이 훨씬 쉬워집니다.
면접관: 순수 함수의 장점은 무엇인가요?
지원자: 테스트가 쉽습니다. 외부 의존성이 없어서 입력만 주면 출력을 검증할 수 있어요. 또한 참조 투명성 덕분에 결과를 캐싱(메모이제이션)할 수 있고, 병렬 처리 시 경쟁 상태가 발생하지 않습니다.
면접관: 함수형 프로그래밍의 단점은요?
지원자: 학습 곡선이 있고, 모든 상황에 적합하지는 않습니다. I/O나 상태 관리가 많은 코드에서는 순수 함수만으로 구현하기 어렵습니다. 적절히 혼용하는 것이 현실적입니다.
리뷰어: 이 reduce 체인이 너무 길어요. 가독성이 떨어지네요.
작성자: 함수형 스타일로 작성하려고요.
리뷰어: 함수형이 좋지만 과하면 역효과예요. 중간 단계를 의미 있는 변수로 분리하거나, 복잡한 로직은 명명된 함수로 추출하세요.