함수형 프로그래밍의 몇가지 특징

Kyle·2021년 1월 19일
0

함수형 프로그래밍의 특징

함수형 프로그래밍의 특징 및 함수형 프로그래밍을 이해하기 위한 키워드들을 정리해보았습니다.

  • 순수함수
  • 일급함수
  • 불변성
  • 지연평가
  • 무상태 (무상태는 제대로 정리하지 못하고 마무리에 제 개인적인 의견으로만 언급했습니다.)

각각의 키워드들의 순서는 흐름에 관계 없이 제가 학습한 순서대로 정리했습니다.

순수함수

순수함수는 2가지 특성을 지닌 함수입니다.

  • 같은 입력을 받았을 때, 같은 출력을 반환한다.
  • side-effect를 갖지 않는다.

참조 투명성 - 위의 2가지 경우와 처럼 외부에 영향을 주거나, 영향을 받지 않는 것을 참조 투명성이라한다.

같은 입력을 받았을 때 같은 출력을 반환하지 않는 경우

아래와 같은 경우 전역변수 number이 다른 함수 또는 객체에 의해서 변경될 가능성이 있기 때문에 같은 입력에도 다른 출력을 할 수 있습니다.

let number = 10;
const add = (a, b) => a + b + number;

side-effect 발생하는 경우

아래와 같은 경우 array를 인자로 받는다 하여도 참조값을 받아오는 것이기 때문에 원본 array역시 변경됩니다.

let array = [1, 2, 3];
const getlast = (arr) => arr.pop();
getlast(array);

일급 함수

함수를 다른 변수와 동일하게 다루는 것을 일급함수라고 합니다.
일급함수는 아래와 같은 특성이 있습니다.

  • 함수를 매개변수로 사용가능합니다.
  • 함수가 함수를 반환 할 수 있습니다.
  • 함수가 변수에 할당할 수 있습니다.

함수를 매개변수로 사용할 경우

자바스크립트에서 위와 같은 경우는 흔하게 사용됩니다. 주로 고차함수(map,reduce,filter)등에 사용됩니다.

고차함수란? 함수를 인자로 받거나 함수를 결과로 반환하는 함수

const numArray = [1, 2, 3, 4, 5];
const oddNumArray = numArray.filter((v) => v % 2 !== 0);

함수가 함수를 반환하는 경우

아래와 같이 클로져를 활용해서 1을 더해주는 add1함수 3을 더해주는 add5함수등을 만들 수 있습니다.

const add = (a) => (b) => a + b);

const add1 = add(1);
const add3 = add(2);

함수가 변수에 할당

아래와 같이 화살표 함수가 아니더라도 함수 선언식으로도 변수에 할당할 수 있습니다. 또한 객체,Map등 이 있을시에 객체의 value값으로도 설정할 수 있습니다.

const add = function (a, b) {
  return a + b;
};
const mathObj = {};

mathObj.addTwo = add;

mathObj.addTwo(1, 2); //3

불변성

불변성은 메모리에 이미 저장된 어떤 값의 상태를 변경하지 않는 것입니다. 예를들면 함수형 프로그래밍에서 캐시를 구현하기 위해 제안된 것이으로 메모이제이션이 있습니다. 캐시값은 함부로 변경되면 안되기 때문에 클로져를 이용해서 특정함수만 이용 가능하게 만드는 기법입니다.

아래 예시는 피보나치 수열을 메모이제이션으로 작성한 것입니다. 아래 코드에서 cache객체는 fib함수를 이용해서만 추가할 수 있게 되어있습니다. 외부에서는 cache객체에는 접근을 할 수 없게 됐죠. 함수형 프로그래밍에서는 이와 같이 불변성을 유지하면서 코드를 설계해야한다.

const slowFib = (n) => {
  if (n < 2) return n;
  return fib(n - 1) + fib(n - 2);
};

const memoize = (fn) => {
  const cache = {};
  return function (num) {
    if (cache[num]) return cache[num];
    cache[num] = fn(num);
    return cache[num];
  };
};

const fib = memoize(slowFib);

Lazy evalutation 지연평가(연산)

함수형 프로그래밍언어는 지연 평가를 지원합니다. 사실 지원이라는 의미가 정확하게 와닿지는 않습니다. 추구?한다고 생각됩니다. 지연평가란 결과값이 필요할 때 까지 계산을 지연하는 방법입니다.

지연 평가는 불필요한 계산을 하지 않고, 무한 자료구조를 쓸 수 있는 등의 장점이 있습니다.

자바스크립트에서는 제너레이터를 활용해서 지연평가 함수를 만들 수 있습니다.

아래 함수에서 무한루프를 가진 infinity함수가 실행됐음에도 에러는 발생하지 않습니다. 값이 필요할때마다 next()메소드를 이용해서 사용할 수 있습니다.

function* infinity(start) {
  while (true) {
    yield start++;
  }
}
const infinite = infinity();

자바스크립트의 Lodash라는 라이브러리에도 _.chain,_.value함수를 이용해 지연평가를 지원합니다.

마무리

자바스트립트를 공부하면서 Lodash라는 라이브러리를 자주 만나게된다. 그만큼 다양하고 유용한 기능을 제공하고 있다고 생각된다. 언제 Lodash라는 라이브러리를 분석?이라기 보다는 어떻게 이루어져 있는지 살펴보는 시간을 가지면 좋겠다고 생각됐다.

함수형 프로그래밍이라는 것이 너무 낯설었다. 클래스는 클래스의 메소드는 주로 클래스의 속성을 사용하도록 구현된 경우가 많은데 이럴경우 순수함수가 아니게 되고 불변성 또한 잘 이루어지지 않을 수 있다. 클래스를 활용하는 함수형 프로그래밍은 어떤 것인가에 대해서도 궁금하다. 또한 위의 클래스와 같은 상태를 갖고 있지않은채로 프로그래밍을 하는 것이 함수형 프로그래밍이기 때문에 무상태 역시 중요한 특징이 아닌가 생각해본다.

함수형 프로그래밍의 장점에도 불구하고 객체지향 프로그래밍이 많이 활용되는 것은 직관적으로 우리 세계와 비슷하기 때문에 코드이해가 쉬워서 이지 않을까..라고 생각해본다.

본 글은 제가 공부하는 과정에서 작성한 글이기 때문에 부정확할 수도 있습니다. 그럴 경우 댓글로 피드백 주시면 너무 감사하겠습니다!!

참조

profile
Kyle 발전기

2개의 댓글

comment-user-thumbnail
2021년 1월 19일

와웅 함수형 프로그래밍 깔끔 정리하셨네요👍 지연 평가 부분은 어렵네요ㅠㅠ 이 부분을 공부해야겠어요!!📚

1개의 답글