Functional Programming (함수형 프로그래밍)
Functional Programming (함수형 프로그래밍)은,
▶변경 가능한 상태를 불변상태(Immutab)로 만들어 SideEffect를 없앤다.
- f(x) = y. 함수f()에 x 를 입력하면 항상 y라는 결과값이 나온다.
- 함수 안에서 상태를 관리하고 상태에 따라서 결과값이 달라지면 안된다.
- 변수 보다는 상수를 사용해 SideEffect를 차단한다.
▶ 모든 것은 Object(객체)이다.
- 함수형 언어에서는 class외에 함수 또한 객체이다. = value(값)처럼 쓰일 수 있다.
- 변수나 데이타에 할당 할 수 있다.
- 객체의 인자로 넘길 수 있다.
- 객체의 리턴값으로 리턴 할수 있다.
= 함수형 프로그래밍 언어에서는 함수가 1급 객체이다!
+ 함수를 받아서 함수를 반환할 수 있다.
- Higher Order Functions (고차 함수)
- 다른 함수를 이용해서 완전히 새로운 함수를 조립 하는 방법으로 프로그램을 만들 수 있다.
- 콜백 함수, 프로미스, 모나드 등을 사용하여 액션, 효과 또는 비동기 흐름을 추상화하거나 분리시킨다.
- 다양한 데이터 타입에 대해 동작할 수 있는 유틸리티를 만든다.
- 합성 함수나 재사용의 목적으로 커링 함수를 만들거나 인수를 함수에 부분적으로 적용한다.
- 함수 목록을 가져오고, 입력 함수의 합성을 반환한다.
▶ 코드를 간결하게 하고 가독성을 높여 구현할 로직에 집중 시킨다.
- boilerplate(일을 위한 일들)를 제거하여 실제 구현할 로직에만 집중 가능하고, 내부에 직접적인 함수 호출을 통해 가독성을 높일 수 있다.
▶ 동시성 작업을 보다 쉽게 안전하게 구현한다.
- 불변 상태의 값을 사용해, 여러 스레드에서 접근하더라도 SideEffect를 발생시키지 않는다.
- Lock, UnLock 같은 보호장치도 필요 없다.
- 데이터 변경이 불가능하기 때문에 기존 데이터의 복사본을 만들어 주는 method가 필요하다.
ex) JavaScript의 Array.map, Array.reduce
const schools = [
"Yorktown"
"Washington",
"Wakefield"
];
// Array.map (맵핑): 모든 원소에 'High School' 문자열 추가된 새로운 배열 만들기
const highSchools = (schools.map(school => `${school} High School`));
console.log(highSchools.join("\n"));
// Array.reduce (축약): 배열에서 최대 값 찾기 (배열을 하나의 수로 변환)
const result = [21, 18, 42, 40, 64, 63, 24].reduce((max, num) => num > max ? num : max, 0);
console.log(result); // 64
// Array.join (합치기): 콤마(,)로 각 학교를 구분한 문자열 얻기
console.log(schools.join(",")); // "Yorktown", "Washington", "Wakefield"
// Array.filter (걸러내기): 'W'로 시작하는 학교만 있는 새로운 배열 만들기
// 원소를 제거하는 경우 Array.pop, Array.slice가 아닌 순수함수인 filter를 사용할 것
console.log(schools.filter(school => school[0] === "W")); // ["Washington", "Wakefield"]
▶ pure function
- 동일한 argument(인자) 입력에 대해 항상 동일한 return(출력)값을 반환 한다.
- side-effects가 없다 (프로그래머가 바꾸고자 하는 변수 외에는 바뀌어서는 안된다.)
- 함수와 데이터를 중점으로 생각한다.
// 순수하지 않습니다 (반환값 없이 부가 효과를 이용하고 있습니다)
function addTaco(array) {
array.push("taco");
}
// 순수하지 않습니다 (인자 대신 공유 변수를 이용하고 있습니다)
function addTaco() {
return [...globalArray, "taco"];
}
// 순수합니다
function addTaco(array) {
return [...array, "taco"];
}
- 순수 함수는 프로그래머가 모든 것을 예측하고 통제할 수 있어야 한다!
(예측이 가능하니, 디버그가 쉬우며 테스트하는 것은 더욱 쉽다. )
- 프로그램의 의미를 변경하지 않고 결과 값으로 함수 호출을 대체할 수 있는 referentially transparent(참조 투명성) 덕분에, 함수 결과를 캐싱하여 반복적으로 사용 할 수 있는 memoization(메모이제이션) 최적화가 가능하다.
- Function composition (합성 함수)
→ 새로운 함수를 만들어거나 계산하기 위해 둘 이상의 함수를 조합하는 과정을 말한다. 함수형 프로그램은 여러 작은 순수 함수들로 이루어져있기 때문에 이 함수들을 연쇄적으로 또는 병렬로 호출해서 더 큰 함수를 만드는 과정으로 전체 프로그램을 구축해야 한다.
→ 메서드 체이닝 방식의 합성함수
const sum = (a, b) => a + b
const square = x => x * x
const addTen = x => x + 10
const computeNumbers = addTen(square(sum(3, 5))) // 74
// compose는 함수를 연쇄적으로 호출하면서 반환값을 전달한다
const compose = (...fns) =>
fns.reduce((prevFn, nextFn) =>
(...args) => nextFn(prevFn(...args)),
value => value
);
// compose의 사용
const compute = compose(
addTen,
square,
sum
)
compute(3, 5) // 74
참고
칼럼:
https://blog.ull.im/engineering/2019/04/07/functional-programming-with-javascript-in-3-steps.html
https://www.zerocho.com/category/JavaScript/post/576cafb45eb04d4c1aa35078
http://jeonghwan-kim.github.io/js/2017/04/03/high-order-function-in-javascript.html
'Programming' 카테고리의 다른 글
프론트엔드 개발을 위한 서비스 구조 (Typescript, React, Styled-components, React-query, MobX, React-intl) (0) | 2023.08.15 |
---|---|
[Programming] Observer Design Pattern (0) | 2020.07.11 |
[Programming] Non blocking / Blocking (0) | 2020.07.09 |
[Programming] Programming_1 (Object Oriented / Procedural Programming) (0) | 2020.07.06 |
댓글