JS로 알아보는 함수형 프로그래밍(1)

서경·2022년 1월 18일
0

JS

목록 보기
1/2
post-thumbnail

들어가기 앞서

해당 글은 인프런의 자바스크립트로 알아보는 함수형 프로그래밍(ES5)(유인동) 강의를 수강하고 이해한 내용을 바탕으로 재구성한 글입니다.


객체지향과 함수형

가장 흔하게 접할 수 있는 객체지향과 비교해보겠습니다.

// 객체지향
duck.moveLeft();
duck.moveRight();
dog.moveLeft();
dog.moveRight();

// 함수형
moveLeft(dog);
moveRight(duck);
moveLeft({ x: 5, y: 2});
moveRight(dog);

예제처럼 객체가 우선 나오면 객체지향형, 함수가 우선 나오면 함수형 프로그래밍이라고 불 수 있습니다.

객체지향형의 경우 데이터를 우선 디자인하고, 데이터에 맞춰 메서드를 구현합니다.

반대로, 함수형 프로그래밍에서는 함수를 우선 디자인하고, 구현한 함수에 맞춰 데이터셋을 구현합니다.

그래서 함수형 프로그래밍이 뭔가요?

위에서 함수형 프로그래밍에 대한 감을 잡으셨다면 이제 입문하도록 해봅시다.

함수형 프로그래밍이란 부수 효과(side effect)를 지양하고 조합성을 강조하는 프로그래밍을 말합니다.

여기서 부수 효과를 지양한다는 것은 곧 순수함수를 만든다는 것이고, 조합성을 강조한다는 것은 모듈화 수준을 높인다고 할 수 있습니다. 즉, 순수함수들의 조합으로 프로그래밍을 해나간다고 볼 수 있습니다.

이 말을 보고 한 번에 이해가 가지 않더라도 괜찮습니다!😄

다음 예제를 읽다 보면 저절로 이해가 갈 것입니다.

const c = 20;
function add1(a, b) {
  return a + b + c;
}

var d = 10;
function add2(a, b) {
  return a + b + d;
}

예제에 앞서, 우선 우리는 순수함수에 대해 알아야 합니다.

- 순수함수 : 외부 상태에 영향을 받지도 끼치지도 않는 함수를 말합니다. 따라서 동일한 값을 넣으면 항상 동일한 결과를 반환한다는 특징을 가집니다.

이 내용 역시 한 번에 이해하지 않더라도 괜찮습니다! 우선 예제들을 살펴봅시다.

다음과 같은 경우 add1는 순수함수고, add2는 순수함수가 아닙니다. add1의 경우 입력하는 값이 같으면 항상 같은 값을 돌려주는 데 반해, add2는 그렇지 않습니다.

console.log(add2(1, 2)); // 13
c = 20;
add2(1, 2); // 23

add2의 경우 d라는 외부 변수를 받아서 사용하기 때문에 d가 바뀌게 되면 a, b에 같은 값이 들어가더라도 다른 값을 반환하기 때문입니다.

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

또한 add3의 경우도 순수함수가 아닙니다. add3 자체는 a, b에 같은 값을 넣으면 항상 같은 값을 반환하지만, 외부 상태에 대해 영향을 끼치기 때문입니다.

이렇게 외부 상태에 영향을 끼치는 것을 부수효과(side effect)를 가진다고 합니다.

그렇다면 함수형 프로그래밍에서는 객체의 값을 변형할 수 없을까요?

함수형 프로그래밍에서는 객체의 값을 변경하는 대신, 새로운 객체를 생성해 대체하는 방식으로 작업을 수행합니다.

var obj1 = { val: 10 };
function add4(obj, b) {
  return { val: obj.val + b };
}

즉, 모든 값(초기값, 외부 상태, 인자 등)을 변화시키지 않으면서 프로그래밍하는 방식을 함수형 프로그래밍이라고 할 수 있습니다.

함수형 프로그래밍에서 순수함수

순수함수의 중요한 특징 중 하나는 평가하는 시점이 정해져 있지 않다는 점입니다. 이것은 함수형 프로그래밍에서 매우 중요한 특징입니다.

비순수함수의 경우 외부요인이 값에 영향을 주기 때문에 평가 시점에 따라 로직이 정해집니다.

그러나 순수함수의 경우 항상 같은 값을 반환하기 때문에 평가 시점을 개발자가 다룰 수 있어 비순수함수에 비해 조합성을 강조할 수 있는 코딩이 가능해집니다. (심지어 다른 쓰레드나 공간에서 평가할 때도!) 따라서 안전하고 다루기 쉬운 함수를 만들 수 있다.

또 순수함수라는 특징과 함께 일급함수라는 특징을 활용해 모듈화를 쉽게 진행할 수 있습니다.

- 일급함수 : 함수를 값으로 다룰 수 있는 특징을 가지는 함수를 말합니다. 즉, 변수에 담거나 인자로 넘기거나 하는 것들이 가능한 것을 말합니다.

function f3(f) {
  return f();
}

conosole.log(
  f3(function () {
    return 10;
  })
);

console.log(
  f3(function () {
    return 20;
  })
);

함수 f3의 경우, 함수를 받아서 값을 받아오는 역할을 합니다. f3의 내부 함수는 값을 결정하는 역할을 하는데, 이런 식으로 일급함수라는 특징을 이용해 각자의 역할을 분리할 수 있습니다.

function add_maker(a) {
  return function (b) {
    return a + b;
  };
}

var add10 = add_maker(10);
var add5 = add_maker(5);

console.log(add10(10)); // 20
console.log(add5(10)); // 15

일급함수는 클로저와 함께 묶어서 사용하는 경우도 잦습니다. add_maker의 예제 처럼 add10에 add_maker(10)의 값을 저장해 놓고 원할 때 추가적인 값을 넣어서 원하는 때에 평가할 수 있습니다. 아니면 add5에 5라는 값을 저장해 놓고 같은 로직을 통해 원할 때 평가할 수도 있습니다.

여기서 또 하나의 특징은 add_maker는 순수함수를 반환한다는 점입니다. 인자 a는 add_maker 내부에서 변경되지 않고, b와 더해지기만 합니다.

즉, 외부에 영향을 끼치지 않기 때문에 순수함수를 반환한다고 할 수 있습니다. 따라서 함수를 값으로 다룰 수도 있고 평가 시점이 관계 없다는 것은 그러한 이유입니다.

이러한 특징을 이용해 함수형 프로그래밍을 활용해 반복문을 실행해 놓은 결과, 비동기 결과 등을 받아뒀다가 이용할 수도 있습니다.

함수형 프로그래밍은 애플리케이션, 함수의 구성요소, 더 나아가서 언어 자체를 함수처럼 여기도록 만들고, 이러한 함수 개념을 가장 우선순위로 놓는다.

함수형 사고방식은 문제의 해결 방식을 동사(함수)들로 구성(조합)하는 것

- 마이클 포거스[클로저 프로그래밍의 즐거움]에서 -

피드백은 항상 환영합니다!! 🥰

profile
Happy Hacking!

0개의 댓글