함수형 프로그래밍 (Functional Programming)
in Web
본 글은 로버트 C.마틴 저자(송준이 엮음)의 [클린 아키텍처: 소프트웨어 구조와 설계의 원칙] 도서를 읽고 작성하였습니다.
6.1. 정의
- 자료처리를 수학적 함수의 계산으로 취급하고 상태와 가변 데이터를 멀리하는 프로그래밍
- 함수형 프로그래밍 언어 :
클로저,스칼라,하스켈
등자바스크립트, 코틀린, 파이썬
등에도 최근 버전에 함수형 프로그래밍 문법이 추가되었음
6.2. 특징
6.2.1. 람다 계산 (Lambda Calculus)
- 알론조 처치 Alonze Church가 고안한 람다 계산법을 기반으로 함
6.2.2. 순수 함수 (Pure function)
- 입력 값이 동일하면 결과가 동일하게 리턴되는 수학함수와 동일함
- 함수의 실행이 프로그램의 실행에 영향을 미치지 않음
- 함수 내부에서 인자의 값을 변경하거나 프로그램 상태를 변경하는 Side Effect가 없음
계산 절차를 포함하더라도 순수 함수로 만들면 부작용이 없음
function add(a, b) { return a + b; } const result = add(2, 3);
6.2.3. 불변성 (Immutable)
- 람다 계산법의 근간이 되는 개념으로 심볼의 값이 변경되지 않는다는 개념
가변 변수를 사용하는 대신에 심볼에 값을 할당하면 그 값은 변경되지 않음
- 쉽게 생각해서 데이터의 변경이 필요한 경우 원본 데이터 구조를 변경하지 않고 그 데이터의 복사본을 만들어서 일부를 변경한 후, 변경한 복사본을 사용해 작업을 진행함
const person = { name: "jongmin", age: "26" }; function increaseAge(person) { return { ...person, age: person.age + 1 }; }
6.2.4. 참조투명성과 부작용
- 프로그램 동작의 변경없이 관련 값을 대체할 수 있다면 표현식을 참조 상 투명하다고 함
- 참조 상 투명한 함수를 평가하게 되면 동일한 인자에 대해 동일한 값을 반환
- 순수 함수로 만들면 함수 외부에 값이나 객체를 참조하거나 의존적으로 동작하지 않기 때문에 참조 투명성을 가지고, 부작용이 없음
- 부작용이 있는 함수는 입력값이 동일해도 함수 외부에 따라서 다른 값이 리턴됨
6.2.5. 람다 혹은 클로저(closure)
- 클로저는 람다계산식(Lambda Calculus) 구현체
- 이름 없는 함수(anonymous function)로 리터럴하게 작성 가능
- 리터럴은 데이터(값) 그 자체를 뜻함
- 즉, 변수에 넣는 변하지 않는 데이터를 의미
- 선언된 범위(scope)에서 접근 가능한 변수를 캡처해서 저장하고 닫힘
- JS 클로저의 경우에는 캡처한 변수를 참조(reference)함
6.3. 1급 객체
함수가 1등 시민(first-class citizen) 혹은 1급 객체
- 함수를 타입으로 지정할 수 있음
- 인자값(파라미터)으로 넘길 수 있음
- 반환값(리턴값)으로 사용할 수 있음
- 마치 함수도 객체처럼 변수나 함수의 인자, 리터럴하게 다룰 수 있다는 의미
const addTwo = (num) => num + 2; const multiplyTwo = (num) => num * 2; const transform = (numbers) => numbers.map(addTwo).map(multiplyTwo); console.log(transform([1, 2, 3, 4])); // [6, 8, 10, 12]
6.4. 고차함수
함수를 더 추상화하면 차원이 높아지는 고차함수로 표현할 수 있음
- 함수를 인자로써 전달할 수 있어야함
함수를 반환값으로 또 다른 함수를 사용할 수 있음
const addInform = (name) => (age) => age + name; const jongmin = addInform("종민"); console.log(jongmin("96"));
JS 컬렉션 인터페이스로는 map, filter, reduce가 있음
- 이러한 인터페이스가 고차함수의 대표적 예시
6.5. 장단점
6.5.1. 장점
- 높은 수준의 추상화 제공
- 함수 단위의 코드 재사용 수월
- 불변성을 지향하기 때문에 프로그램 동작 예측이 수월
6.5.2. 단점
- 순수함수를 구현하기 위해서는 코드의 가독성이 떨어질 수 있음
- 함수형 프로그래밍에서는 반복이 for문이 아닌 재귀를 통해 이루어지는데(deep copy), 재귀적 코드 스타일은 무한 루프에 빠질 수 있음
- 순수함수를 사용하는 것은 쉬울 수 있지만 조합하는 것은 쉽지 않음
Reference
- 로버트 C.마틴, 2019, 클린 아키텍처: 소프트웨어 구조와 설계의 원칙
- https://jongminfire.dev/%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%B4%EB%9E%80
- https://ko.wikipedia.org/wiki/%EC%B0%B8%EC%A1%B0_%ED%88%AC%EB%AA%85%EC%84%B1