FP Workshop - 0. FP Basic


Chapter 0: FP Basic

함수형 프로그래밍을 접하기 전에 알아야할 기본 지식들

Imperative

Imperative

Functional

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 }
...