FP Workshop - 0. FP Basic
Table of contents
Chapter 0: FP Basic
함수형 프로그래밍을 접하기 전에 알아야할 기본 지식들
Imperative
Functional
1. Pure Function (순수함수)
순수함수란
- 같은 input ⇒ 같은 output
- 언제 어디서 실행하든지 항상 같은 결과
- 부수효과(side effect)가 없음
javascript
function PureAdd(a, b) {
return a + b;
}
let b = 1;
function NonPureAdd(a) {
return a + b;
}
function SideEffectAdd(a, b) {
console.log("hi!");
return a + b
}
2. First Class Function (일급함수)
함수를 값으로 다룰 수 있다
javascript
// Can assign to variable
const add = (a, b) => a + b;
// Can pass function as parameter
[1, 2, 3].reduce(add);
// Function can return another function
const subtract = (a) => (b) => a - b
3. Iterator Protocol
객체가 iterable 하기 위해서는 iterable protocol 을 따라야 합니다.
javascript
// Iterate Map
for (const el of new Map([['a', 1], ['b', 2]])) {
console.log(el)
}
// Iterate Set
for (const el of new Set([1, 2, 3])) {
console.log(el)
}
// Iterate Array
for (const el of ['lodash', 'ramda', 'fxts']) {
console.log(el)
}
// Iterate plain object
const obj = {a: 1, b: 2}
for (const el of obj) {
console.log(el) // Uncaught TypeError: obj is not iterable
}
기본 객체를 iterable 하도록 만들어 봅시다.
javascript
// Declare non iterable object
const obj = {
'a': 1, 'b': 2, 'c': 3,
}
// Set [Symbol.iterator] property
obj[Symbol.iterator] = function() {
let i = 0;
const values = Object.values(this);
return {
next() {
return i == values.length
? { done: true }
: { value: values[i++], done: false }
},
[Symbol.iterator]() { return this; } // well-formed iterator
}
}
// Now we can iterate `obj` with `for of` statement.
for (const el of obj) {
console.log(el); // 1 2 3
}
4. Generator
제너레이터를 사용하면 iterable 한 객체를 쉽게 구현할 수 있습니다.
js
function *gen() {
yield 1;
yield 2;
yield 3;
}
const iter = gen();
iter.next(); // { value: 1, done: false }
iter.next(); // { value: 2, done: false }
iter.next(); // { value: 3, done: false }
iter.next(); // { value: undefined, done: true }
제너레이터를 응용하면 무한으로 iterable 한 iterator 를 만들 수 있습니다.
js
function *infinite() {
let i = -1;
while (true) {
yield ++i;
}
}
const iter = infinite();
iter.next(); // { value: 1, done: false }
iter.next(); // { value: 2, done: false }
iter.next(); // { value: 3, done: false }
...