본문 바로가기
JavaScript/함수형 프로그래밍

순수 함수

by Vintz 2021. 9. 20.
반응형

성공적인 프로그래밍은 무엇을 의미 할까?

  • 모든 프로그래밍 패러다임은 성공적인 프로그래밍을 위해 존재한다.
  • 좋은 프로그램을 만드는 일은 곧 성공적인 프로그래밍을 의미한다.
  • 좋은 프로그램은 사용성, 성능, 확장성, 기획 변경에 대한 대응력 등이 좋다.
  • 위와 같은 사항들을 효율적이고 생산적으로 이루는 일이 성공적인 프로그래밍이다.

그 중 함수형 프로그래밍은..

함수형 프로그래밍은 성공적인 프로그래밍을 위해 부수 효과를 최소화, 조합성을 강조하는 프로그래밍 패러다임이다.

  • 부수 효과를 최소화 한다? -> 순수 함수를 만든다.
  • 조합성을 강조한다? -> 모듈화 수준을 높인다.

순수 함수

순수 함수란 들어온 인자가 같다면 항상 동일한 결과를 리턴하는 함수를 뜻한다. 그리고 순수함수는 함수가 받은 인자 외에 다른 외부의 어떤 상태에 영향을 끼치지 않는 함수를 의미한다. 리턴값 외엔 외부와 소통을 하지 않는다.

  1. 들어온 인자가 같다면 항상 동일한 결과를 리턴한다.
  2. 함수가 받은 인자 외엔 다른 외부의 어떤 상태에 영향을 끼치지 않는다.
  3. 리턴값 외엔 외부와 소통을 하지 않는다.

위와 같은 사항들은 순수 함수를 의미한다.

// ✅ 순수 함수
function add(a, b) {
  return a + b;
}

console.log(add(10, 5)); // 15
// 항상 동일한 인자를 주면 동일한 결과값을 리턴한다.
console.log(add(10, 5)); // 15
console.log(add(10, 5)); // 15

위 예제의 add()는 리턴 값으로 결과를 만드는 것 외에 외부의 상태에 영향을 끼치지 않고(부수 효과 ❎), 항상 동일한 인자를 주면 동일한 결과값을 리턴하기 때문에 add()는 순수 함수이다.

 

그렇다면 동일한 인자를 주었을 때, 상황에 따라 다른 결과값을 리턴하는 함수는 어떤 함수일까?

// ❎ 순수 함수가 아닌 함수
let c = 10;
function add2(a, b) {
  return a + b + c;
}

console.log(add2(10, 5)); // 25
c = 20;
console.log(add2(10, 5)); // 35

위 예제에선 동일한 인자를 넣었지만 c20으로 초기화한 시점 이후엔 결과값이 달라진다. 똑같은 add2()가 다른 결과값을 낸 것이다. 따라서 add2()는 순수 함수가 아니다.

 

⚠️ 만약 변수 c가 변하지 않는 값인 상수(constant)로써 존재하게 된다면 add2()는 순수 함수이다.

 

또 다른 예제를 보자.

// ❎ 순수 함수가 아닌 함수
let c = 20;
function add3(a, b) {
  c = b;
  return a + b;
}
console.log(c); // 20
console.log(add3(20, 30)); // 부수 효과 발생
console.log(c); // 30

c라는 변수가 add3()를 실행하면 20에서 30으로 값이 변경된다. add3()는 결과값 외에 다른 방식으로 외부 상태에 직접 관여를 하고 있다. 이를 부수 효과가 있다고 말하며 순수 함수가 아니다.

 

일반적으로 데이터를 다룰 때 그냥 숫자, 문자 이런 값보다는 객체를 주로 다루게 된다. 이번엔 객체로 예를 들어보자.

// ✅ 순수 함수가 아닌 함수(객체)
const obj1 = { val: 10 };
function add4(obj, b) {
  obj.val += b;
}

console.log(obj1.val); // 10
add4(obj1, 20);
console.log(obj1.val); // 30

리턴값도 없고, 인자에 들어오는 값의 상태를 직접 변경하고 있다. add4()를 실행하면 변수 obj1val 값이 10에서 30으로 변경된다.

 

⚠️ 위의 예제가 문제라는 것을 말하는 게 아니며, 순수 함수가 아니라는 것을 말하고 있다. 그렇다면 함수형 프로그래밍에선 이 객체를 어떻게 다룰까?

원래의 객체는 그대로, 값을 복사해 변형 후 새로운 결과값을 리턴

// ✅ 순수 함수(객체)
const obj1 = { val: 10 };
function add5(obj, b) {
  return { val: obj.val + b };
}

console.log(obj1.val); // 10
const obj2 = add5(obj1, 20);
console.log(obj1.val); // 10
console.log(obj2.val); // 30

위 예제는 인자로 들어오는 obj1을 참조만 할 뿐 값의 상태를 직접 변경하지 않는다. 그리고 같은 구조에 값을 변경한 새로운 객체를 리턴한다. 따라서 add5()를 실행해도 obj1val 값은 그대로이다.

 

add5()를 실행한 객체인 obj2val 값에 20을 더한 30을 출력한다.

 

그래서 함수형 프로그래밍에서는 값을 변형하거나 다룰 때 최초 초기화된 값(기존값)을 건들지 않고 값을 다룬다.

  1. 최초 초기화된 값을 건들지 않는다.
  2. 외부 상태의 값을 변형시키지 않는다.
  3. 인자로 받은 값을 직접 변경하지 않는다.

즉 순수 함수는 주어진 입력값에만 의존하여 반환값을 내는 함수라고 볼 수 있다.

순수 함수의 특징과 이점

  1. 항상 동일한 인자를 넣으면 동일한 결과를 리턴한다.
  2. 평가 시점*이 중요하지 않다.
평가 시점(evaluation time)* - evaluation이란 단어는 수학에서 값을 구함이라는 명사다. 따라서 함수를 평가한다는 것은 함수를 수행해서 결과를 구한다는 말이다. 결국 함수의 평가 시점이란 함수에 파라미터를 넘기고, 수행하는 시점이라고 봐도 무방하다. - 안JAVA먹지 블로그

2번 또한 순수 함수의 중요한 특징인데, add2()를 예로 들어보자.

// ❎ 순수 함수가 아닌 함수
let c = 10;
function add2(a, b) {
  return a + b + c;
}

console.log(add2(10, 5)); // 25
c = 20; // c가 변경된 후 add2()의 값도 변경되었다.
console.log(add2(10, 5)); // 35

add2()의 경우 c가 변경되기 전에 평가했는지와 변경되고 나서 평가했는지에 따라 값이 달라질 수 있기때문에 순수 함수가 아닌 함수는 평가 시점이 중요하고, 평가 시점에 따라 로직이 정해진다.

 

하지만 반대로 순수 함수는 평가 시점과 무관하게 동일한 결과를 리턴하기 때문에 훨씬 조합성을 강조(모듈화 ⬆️)할 수 있다. 이 말은 평가 시점을 개발자가 다룰 수 있게 된다는 뜻이다. 다시 말해 순수 함수를 다른 함수의 인자로 넘긴다던지, 전혀 다른 공간에서 함수를 평가시켜도 항상 동일한 결과를 리턴할 것이기 때문에 안전하고, 다루기 쉬운 함수가 된다.(재사용성 ⬆️)

참고

자바스크립트로 알아보는 함수형 프로그래밍 (ES5) - 인프런

 

[무료] 자바스크립트로 알아보는 함수형 프로그래밍 (ES5) - 인프런 | 강의

마플(http://www.marpple.com)의 CTO 유인동님이 알려주는 함수형 프로그래밍에 대한 강좌 입니다. 함수형 프로그래밍으로 라이브러리를 직접 만들어가며 함수형 프로그래밍의 패러다임과 코딩의 즐거

www.inflearn.com

함수형 자바스크립트 9. 지연평가와 함수형 프로그래밍 요약 - 안JAVA먹지
반응형

'JavaScript > 함수형 프로그래밍' 카테고리의 다른 글

함수형 자바스크립트 기본기 정리  (0) 2021.10.03
일급 함수  (0) 2021.09.21