TIL4. 함수형 프로그래밍

imloopy·2022년 3월 24일
0

Today I Learned

목록 보기
4/56

틀린 정보가 있을 수 있습니다. 지적은 언제든지 환영합니다.

Today I Learned

평소에 코드를 작성할 때 주로 클래스를 만들고, 클래스 내부에서 뭔가를 다루는 형태로 사용을 했었다. 리액트의 useState도 그렇고, 최대한 불변성을 보장받을 수 있도록 라이브러리가 구성되는 경우가 점점 많아지는것 같다. 이러한 것들을 가능하게 해주는 함수형 프로그래밍이 무엇인지, 장 단점은 무엇인지 한번 정리해보았다.

함수형 프로그래밍에 앞서...

프로그램의 구성은 순차, 분기, 반복, 참조로 이루어진다. 이는 일반적인 모든 프로그래밍 패러다임에 해당된다.
우리가 주로 다루는 절차 지향형, 객체 지향형, 명령형, 선언형, 함수형 등의 프로그래밍 패러다임은 위의 4가지 요소를 어떤식으로 이용하는 지에 따라 나뉜다.

함수형 프로그래밍

함수형 프로그래밍은 어떻게(How) 할 건지를 나타내는것 보다 무엇(What)을 할 건지를 설명하는 방식이다.

함수형 프로그래밍의 정의

함수형 프로그래밍은 자료 처리를 수학적 함수의 계산으로 취급하고, 가변 데이터를 멀리하는 프로그래밍 패러다임이다. 함수형 프로그래밍은 데이터를 함수를 이용하여 새로운 데이터를 만들어나가는 데이터 파이프라인 형태를 가진다.

함수형 프로그래밍의 특징

함수형 프로그래밍에서 함수는 상태가 존재하지 않는다.

다음의 경우는 함수형 프로그래밍이 아니다.

let ret = 0
function sum(a: number): number {
  ret = a
  return ret
}

다음의 함수는 함수형 프로그래밍 패러다임과 일치한다.

function sum(a: number, b: number): number {
  return a + b
}

첫번째 함수는 함수가 ret이라는 전역 상태를 바꿀 수 있다. 즉 함수가 상태에 영향을 미치므로 순수 함수가 아니다. 두 번째 함수는 함수 내부에 외부 상태를 바꾸는 어떠한 요소도 존재하지 않는다. 함수는 함수 그 자체이기 때문에, 순수 함수다. 그리고 이는 함수형 프로그래밍과 다른 패러다임에서 나타나는 가장 큰 차이점이다.

순수 함수는 내부에 상태를 두는 것을 허용하지 않기 때문에, 이에 다음의 장점들을 가지고있다.

함수형 프로그래밍의 장점

  • 상태가 존재하지 않기 때문에 이에 따라 발생하는 사이드 이펙트가 없다.
  • 재사용성이 높다. 예를 들어, 자바스크립트에서 배열과 관련된 Array.reduce(), Array.forEach(), Array.map(), Array.filter()등은 어떠한 배열에 대해서도 사용이 가능하다.
  • 코드가 짧고 간결하다.
// 일반적인 명령형 프로그래밍 패러다임
let a = [1, 2, 3, 4, 5];
for (let i = 0; i < 5; ++i) {
  if (a[i] % 2 === 0) {
    console.log(a[i]);
  }
}

/**
 * 함수형 패러다임 + 선언형을 지향하는 함수
 * 명령형으로 작성하는 함수에 비해 훨씬 간결하고 눈에 잘 들어온다.
 **/
[1, 2, 3, 4, 5]
  .filter((item) => item % 2 === 0)
  .forEach((item) => console.log(item));

함수형 프로그래밍의 단점

그러나 항상 함수형 프로그래밍이 옳은 방법만은 아니다.

  • 상태가 없기 때문에 변수 조작이 안된다.
    모든 프로그램은 상태를 가지므로, 함수형 프로그래밍만으로 프로그래밍을 작성하는 것은 쉬운 일이 아니다.
  • 코드는 간결하지만, 더 많은 메모리를 차지할 수 있다.
// 명령형 패러다임
const n = 1000;
const arr: Array<number> = Array(n + 1).fill(0)
arr[0] = 1
arr[1] = 1
for (let i = 2; i < n + 1; ++i) {
  arr[i] = arr[i - 1] + arr[i - 2]
}
console.log(arr[n])

// 순수 함수로 작성
function fib(n: number) {
	if (n <= 1) return 1
  return fib(n - 1) + fib(n - 2)
}

순수 함수로 작성한 두 번째 함수 역시 동적 계획법을 적용하면 첫번째 함수와 비슷한 시간에 문제를 해결할 수 있으나, 재귀 함수는 시스템의 콜스택을 사용하므로, 재귀 깊이가 깊어질수록 메모리가 오버되어 스택오버플로우가 발생할 가능성이 매우 높다.

  • 코드를 짧고 간결하게 작성하는 것은 많은 숙련도를 요구한다. 오히려 시간이 더 오래 걸릴 가능성이 높다.

그럼에도 불구하고 함수형 프로그래밍을 익혀두면 좋은 이유

"일반적인 프로그래밍은 그냥 생각하면 되는 것이고, 함수형 프로그래밍은 기존과 다르게 생각하는 방법을 알려줄 것이다. 그러므로 당신은 아마도 예전 방식으로 절대 돌아가지 않을 것이다."

함수형 프로그래밍은 프로그래밍 언어나 방식을 배우는것이 아니라 함수로 프로그래밍하는 사고를 배우는것이라고 할 수 있다.
즉, 새로운 계산방법을 배우는 것처럼 사고의 전환을 필요로 한다. 다양한 사고방식으로 프로그래밍을 바라보면 더욱 유연한 문제해결이 가능해진다.

느낀점

함수형 프로그래밍은 확실히 보기에 깔끔하고 불변성을 보장한다는 측면에 있어서 강력한 도구임은 분명하다. 자바스크립트는 기본적으로 객체 지향형 언어이지만, 여러 순수함수들이 내장되어있어 함수형 패러다임으로 프로그래밍 작성이 가능하다. 사고의 폭을 넓히기 위해서 함수형 프로그래밍으로 사고하는 연습을 계속 진행해야겠다.

출처

함수형 프로그래밍 요약 - velog
함수형 프로그래밍은 선언형 프로그래밍과 가깝다.
https://mangkyu.tistory.com/111

0개의 댓글