[JavaScript] 함수형 프로그래밍의 순수 함수

함수형 프로그래밍

부수 효과를 없애고 순수 함수를 만들어 모듈화 수준을 높이는 프로그래밍 패러다임

  • 부수 효과: 외부 상태를 변경하거나 함수로 들어온 인자 상태를 변경하는 것
  • 순수 함수
    • 동일한 입력에 대해 항상 동일한 출력을 반환하는 함수
    • 외부의 상태를 변경하거나 영향을 받지 않는 함수

순수한 함수

function func(a, b) {
  return a + b;
}

console.log(func(2, 2)); // 4

func 함수는 순수하다. 언제나 이 함수를 수백번 실행시켜도 입력값이 2, 2면 출력값이 4로 동일하기 때문이다. 또한 이 함수는 외부의 값에 영향을 주거나 받지 않는다.

순수하지 않은 함수

let c = 1;

function func(a, b) {
  return a + b + c;
}

console.log(func(2, 2)); // 5

c = 2; // c 값이 변경됨

console.log(func(2, 2)); // 6

위 함수는 외부 값인인 c에 영향을 받기 때문에 순수함수가 아니다. c가 변하면 동일한 입력에 대해 출력이 다르기 때문이다.

let c = 1;

function func(a, b) {
  c += 1; // 외부의 값에 변화를 주며, 이를 부수효과라 함
  return a + b;
}

func(2, 2); // 함수 실행

console.log(c); // c 값이 2로 변화됨

위 함수도 함수가 실행되면 외부값인 c를 변경시키기 때문에 순수 함수가 아니며, 이를 부수 효과라 한다.

let obj = {
  a: 1
};

function func(obj) {
  return obj.b = 1; // 인자로 받은 객체에 b 값을 추가하여 리턴
}

func(obj);

console.log(obj); // { a: 1, b: 1 }

객체의 경우도 살펴보자. 위 함수도 외부 obj 객체에 b가 추가되었기 때문에 순수함수가 아니다.

let obj = {
  a: 1
};

function func(obj) {
  return obj; // 인자로 받은 객체를 그대로 리턴
}

let obj2 = func(obj);

위의 경우는 어떨까? 함수 안에서는 객체를 받고 아무런 변화를 주지 않고 리턴하였으며, 새로운 변수에 리턴된 객체를 할당했다. 위 함수에서는 객체에 아무런 변화를 주지 않았으니 순수 함수라고 할 수 있을까?

let obj = {
  a: 1
};

function func(obj) {
  return obj; // 인자로 받은 객체를 그대로 리턴
}

let obj2 = func(obj); // 새로운 변수에 리턴된 객체를 할당

obj2.a = 2; // 새로운 객체 obj2의 a 값을 변경

console.log(obj2); // { a: 2 }
console.log(obj); // { a: 2 }

정답은 아니다. func 함수를 실행하여 새로운 변수에 리턴받은 객체를 할당했으며, 새로운 객체 obj2a 값을 변경하였다. 그랬더니 기존의 obj 객체의 값도 변경이 되었다. 바로 객체의 참조(주소) 값도 같이 복사되어 새롭게 만든 obj2가 변화함에 따라 기존의 obj 객체도 변경되기 때문이다. 이처럼 함수 내에서 직접 값을 변경하지 않았더라도 함수에 들어온 인자값을 그대로 사용하면 순수 함수가 아니다.

let obj = {
  a: 1
};

function func(obj) {

  // 객체의 값만 참조하여 새로운 객체를 리턴
  return {
    a: obj.a,
    b: 2
  };
}

let obj2 = func(obj);

obj2.a = 2;

console.log(obj2); // { a: 2, b: 2 }
console.log(obj); // { a: 1 }

위에서는 인자로 받은 객체를 직접 사용하지 않고 obj.a 값만 참조해서 새로운 객체를 생성하여 리턴하고 있다. 이럴 경우는 참조(주소)값이 복사가 안되기 때문에 obj2 객체의 값이 변경되도 obj의 값이 변경되지 않는다. 그러므로 위 함수는 순수 함수라 할 수 있다.

결론

모든 함수가 순수 할수일 수는 없다. 모든 함수가 순수 함수라면 외부의 어떤 데이터에도 변형을 주지 않기 때문에 프로그램은 구동되지 않을 것이다. 단지, 이런 스타일로 코딩하는것이 함수형 프로그래밍의 패러다임 이며, 이 패러다임의 목적은 외부 상태의 변화를 최소함으로 유지하고, 함수 실행 결과 예측을 용이하게 하여 버그 발생 가능성을 줄이는 것에 목적이 있다.

[번역] JavaScript 함수형 프로그래밍 3단계로 설명하기
순수 함수란 무엇인가요… 별거 없음…
JS 함수형 프로그래밍을 위한 사전 지식 : 순수함수, 일급함수
자바스크립트의 함수형 프로그래밍 1 : 순수 함수란?
순수 함수란? (함수형 프로그래밍의 뿌리, 함수의 부수효과를 없앤다)

updated_at 09-12-2020