반응형
Functional Programming, FP
함수형 프로그래밍은 수학적 함수의 특징을 가진 함수들을 조합하여 프로그램을 작성하는 프로그래밍 패러다임입니다. 함수형 프로그래밍에서는 상태 변경이나 가변 데이터보다는 불변성과 순수 함수의 사용이 중요시됩니다. 따라서 함수형 프로그래밍에서는 함수를 일급 객체로 다루며, 고차 함수, 클로저, 람다식 등을 이용하여 프로그램을 작성합니다.
이를 통해 코드의 재사용성과 가독성을 높일 수 있으며, 동시성과 병렬성 처리도 용이해집니다. 함수형 프로그래밍은 다른 프로그래밍 패러다임과 달리 명령형이 아닌 선언형으로 코드를 작성하므로, 코드의 의도를 파악하기 쉽고 디버깅이 쉬운 특징을 가지고 있습니다.
1) 순수 함수, Pure Functions
- 함수 내에서 외부의 상태값을 참조하거나 변경하지 않습니다.
- 동일한 인자를 넣었을 때 항상 동일한 결괏값을 반환합니다.
- 함수의 실행이 프로그램에 영향을 주거나 부수 효과를 발생시키지 않습니다. ( No SideEffect! )
🔍 Side Effect, 부작용
원래의 목적과 다르게 다른 효과 또는 부작용, 의도치 않은 결과
순수 함수가 아닌 경우
let number = 1; // global variable
function add(x) {
return x + number;
}
❗️위 예시코드는 add함수 안에서 전역으로 선언된 변수 number를 참조하기 때문에 순수함수가 아닙니다.
순수 함수인 경우
function add(x, y) {
return x + y;
}
const answer = add(3, 7);
💡 위 예시 코드처럼 함수 외부의 값을 참조하거나 영향을 주지 않아야 순수함수입니다.
2) 비상태, Stateless & 불변성, Immutability
- 데이터를 변경하지 않고 불변성을 유지해야 합니다.
- 데이터의 변경이 필요하다면 전달받은 데이터를 변경하는 것이 아니라 새로운 데이터로 만들어서 결괏값으로 반환해야 합니다.
비상태, 불변성이 지켜지지 않은 경우
let person = { name: 'infjoon', age: 30 };
function increaseAge(person) {
person.age = person.age + 1;
return person
}
❗️위 예시코드는 전역으로 선언된 Object person의 age 속성의 값을 변경하므로 불변성을 유지하지 못하고 있습니다.
비상태, 불변성이 지켜진 경우
let person = { name: 'infjoon', age: 30 };
function increaseAge(person) {
return { ...person, age: person.age + 1 };
}
💡 위 예시코드는 스프레드 연산자(Spread Opertor)를 사용해 기존 person 속성들을 담고 age 값은 1을 증가시킨 후 새로운 Object를 반환하기 때문에 불변성을 유지합니다.
이 외에도 Object.freeze라는 함수를 사용해서 Object의 불변성을 유지해 줄 수 있습니다.
/* Object.freeze() 메서드는 객체를 동결합니다. 동결된 객체는 더 이상 변경될 수 없습니다. */
let person = Object.freeze({ name: 'infjoon', age: 30 });
function increaseAge(person) {
return Object.freeze({ ...person, age: person.age + 1 });
}
// Throws an error in strict mode
person.age = 33;
3) 선언형, Declarations
- 조건문과 반복문의 사용을 지양하여 재사용성과 가독성을 높입니다.
- 선언형 프로그래밍은 '무엇을 할 것인가'에 주목하고 명령형 프로그래밍은 무엇을 '어떻게 할 것인가'에 주목합니다.
- declarative(선언형) - what to solve
for문을 사용한 경우
let numbers = [ 1, 2, 3 ];
function multiply(numbers, multiplier) {
for (let i = 0; i < numbers.length; i++) {
numbers[i] = numbers[i] * multiplier;
}
}
❗️if, for, switch과 같은 명령문을 사용하지 않아야 합니다.
map으로 대체한 경우
let numbers = [ 1, 2, 3 ];
function multiply(numbers, multiplier) {
return numbers.map(num => num * multiplier);
}
💡 위 예시코드처럼 Javascript에서는 filter, map, reduce 등의 함수형 코드를 사용하며 프로그래밍해야 합니다.
4) 일급 함수, First Class
1급 객체 또는 1급 객체 함수의 특징
- 변수나 데이터 구조안에 담을 수 있습니다.
- 반환값(return value)으로 사용할 수 있습니다.
- 매개변수( Parameter )로 전달할 수 있습니다.
- 할당에 사용된 이름과 관계없이 고유한 구별이 가능합니다.
- 동적으로 프로퍼티( Property ) 할당이 가능합니다.
예시 코드
const addOne = x => x + 1; // 1을 더해주는 함수
const multiplyTwo = y => y * 2; // 2를 곱해주는 함수
const transform = numbers => numbers.map(addOne).map(multiplyTwo);
console.log(transform([ 1, 2, 3, 4 ])); // 출력값: [ 4, 6, 8, 10 ]
5) 고차 함수, Higher-order Functions
고차 함수 특징
- 함수를 인자로써 전달할 수 있어야 합니다.
- 함수의 반환 값으로 또 다른 함수를 사용할 수 있습니다.
예시 코드
const addDrinks = drink => food => food + drink; // 음료를 추가해주는 함수
const cola = addDrinks('🥤'); // 팝콘에 콜라 추가 요청
const beer = addDrinks('🍺'); // 치킨에 맥주 추가 요청
console.log(cola('🍿')); // 출력값: 🍿🥤
console.log(beer('🍗')); // 출력값: 🍗🍺
Reference
반응형
'PROGRAMMING > CS' 카테고리의 다른 글
[CS] 함수(Function)와 메서드(Method) 간단하고 정확하게 알아가기 (feat. Javascript) (26) | 2023.03.25 |
---|---|
[CS] 블로킹과 논블로킹 그리고 동기와 비동기 (feat.Javascript) (36) | 2023.03.21 |
[CS] Argument와 Parameter의 차이 쉽게 이해하기 (feat. 인수 / 인자 / 매개변수 용어 정리) (36) | 2023.03.09 |
URL과 URI의 차이 그리고 URN까지 쉽게 이해하기 (50) | 2023.02.23 |
REST API와 GraphQL, 정의 | 비교 | 장점 | 단점 | 규칙 | 예시코드 | 설치 | 고려할점 (feat.Server API, Node.js) (36) | 2023.02.19 |