부수효과

부수효과(Side Effect)

부가적으로 수행되는 동작으로, 값을 반환하는 것 이외에 부수적으로 일으키는 효과이다. ex:) 상태 변경, 외부에 영향을 미치는 동작 등,

함수형 프로그래밍은 부수효과를 격리시키고 최소화하는 방식으로, 부수효과로만 다뤘던 작업을 순수한것처럼 다룰수 있도록 추상화하는 방식이다.

부수효과를 왜 분리해야할까?

부수효과는 주로 명령적인 방식에서 발생하는 개념으로 어떻게 동작이 이루어지는 구체적으로 작성된다.

사람이 한번에 생각할 수 있는 작업 기억 공간의 용량은 3~5개에 불과하다. 이런 한계와 부수효과가 가지는 다음과 같은 특징들로 인해 코드를 이해하고 예측하기란 불가능에 가까워진다.

  • 변화하는 상태를 모두 기억해야 한다.

  • 코드 실행 순서, 횟수, 분기에 따라 결과가 달라진다.

  • 비동기, 전역상태까지 더해진다면..?

부수효과를 최소화

for, white 은 상태를 변경하고 불변성을 위반하는 부수효과를 가지고 있다. 순수 함수형 프로그래밍에서는 이런 반복적인 작업이 필요할 때 재귀를 사용한다.

// 1부터 100까지 수를 더하는 로직이 명령형(어떻게)방식으로 구체적으로 작성되어 복잡하고 이해하기 어렵다.
function sum_1_to_100() {
  let sum = 0;
  for (let i=1; i<= 100; i++){
    sum += i;
  }
  return sum;
}

// 각각의 동작을 함수로 분리하고 추상화시킴으로써 코드를 더 이해하기 쉽고 예측 가능하도록 리팩토링됨
// loop와 range는 한 번만 만들어두면 재사용 가능
const loop = (fn,acc,list) => {
  if(list.length === 0) return acc;
  const [head, ...tail] = list;
  return loop(fn, fn(acc,head), tail);
}

const range = (start, end) => Array.from(
  {length: end - start + 1},
  (_,index) => index + start
);

const plus = (a,b) => a + b;
// 함수 합성을 이용해서 선언형 방식으로 코드를 작성하게되면 코드가 무슨 동작을 하는지 파악하기 쉬워진다. 
console.log(loop(plus, 0, range(1,100)) //5050

코드를 명령형(어떻게)에서 선언형(무엇을)으로 바꾸면, 사람이 논리적으로 생각하는 것과 동일한 구조로 코드를 표현할 수 있게 되어 가독성이 좋아진다.

리팩토링된 코드를 보면 코드의 길이가 더 늘어났지만, 가독성, 테스트 용이성, 재사용성이 가져오는 이점이 더 크다.

각각의 함수는 작고 한가지 일만 수행하기 때문에 그 동작을 예측하기 쉽고 테스트하기 쉬워진다.

함수 합성은 입출력 타입만 같다면 얼마든지 합성할 수 있다.

효과를 안전하게 추상화하기

  • 숨겨진 부수효과 → 명확하고 순수한 Effect

  • 뒤섞인 코드 → 효과(액션)와 계산이 직교하게 분리

  • 보일러 플레이트 → 재사용하기 쉬운 추상화

  • 제각각인 사용법 → 단순하고 일관된 인터페이스

Last updated