함수형 자바스크립트

3 minute read

해당 포스팅은 서적을 읽고 생각의 변화를 가져온 부분이나, 공감하는 부분을 일부 발췌해 저의 생각과 함께 정리한 내용입니다.

역량이 쌓여감에 따라 와닿지 않았던 부분도 다르게 다가올 수 있기때문에 책을 읽을때마다 포스팅을 수정할 예정입니다.

함수형 프로그래밍?

함수형 프로그래밍은 내가 작성해왔던 코드와 같은 명령형 + 절차적 프로그래밍(아래)을 벗어나

var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for(let i = 0; i <array.length; i++) {
  array[i] = Math.pow(array[i], 2);
}
array; // => [0, 1, 4, 9, 16, 25 ....]

함수형 프로그래밍은 큰틀에서 선언적 프로그래밍 패러다임에 속한다. 내부적으로 코드를 어떻게 구현했는지,

데이터가 어떻게 흘러가는지 밝히지 않은채 연산/작업을 표현하는 프로그래밍 기법이다.

위의 명령형 프로그래밍의 예시로 for문을 예시로 들었는데 for문을 예시로 든 이유는 간단하다.

재사용도 어렵고 다른 연산에 끼워넣기도 어려운 명령형 제어 구조물이기 때문


함수형 프로그래밍의 기본은 불변 프로그램 구축을 전제로 한다.

var counter = 0;
function increment() {
  return ++counter;
}

이 함수는 스코프에 없는 외부 변수 counter를 읽고 수정함으로 불순하다. => 부수효과가 일어나게 된다. (언제 어디서 호출되어 어떤 값이 반환될지 알 수 없다.)

함수 서명(signature)에 없는 변수는 외부 변수다. => 무결성이 깨질 수 있다.

외부 상태에 의존하게되면 재사용이 어렵다.

함수를 개선하는 방법 두가지

  • 긴 함수를 하나의 목적을 가진 짧은 함수로 각각 분리한다.
  • 함수가 해야 할 작업에 필요한 인수를 모두 명시하여 부수효과 개수를 줄인다.

함수형 프로그래밍은 작은 단위로 잘게 쪼게는 것에부터 시작한다.

그리고 데이터는 불변성질로서 유지한다. => 비단 sort만하더라도 불변성에서 어긋나게 된다.

함수형 프로그래밍은, 외부에서 관찰 가능한 부수효과가 제거된 불변 프로그램을 작성하기 위해 순수함수를 선언적으로 평가하는 것이다.

함수를 데이터를 절대 변경하지 않는 고정된 작업단위로 바라본다면 확실히 잠재적인 버그는 줄게 될것이다.

함수형 프로그래밍은 고수준에서 보면 사실상 분해(프로그램을 작은 조각들로 쪼갬)와 합성(작은 조각들을 다시 합침) 간의 상호작용이라고 할 수 있다.

FP의 중요한점은 모듈화와 단일성! => 모름지기 함수는 저마다 한가지 목표만 바라봐야 한다는 사상이다.

루프나 분기 같은 명령형 흐름제어는 조건에 따라 실행 경로가 각각 달라지는 까닭에 함수는 더 복잡해지고 테스트는 감히 생각조차 할 수 없다.

객체지향 설계를 FP가 완전히 대체하는 걸까? 이는 코들르 적용한다고 전부를 얻거나 전부를 잃는 식의 접근 방법이 아님.

이미 객체지향형 아키텍처와 FP를 병용하여 혜택을 본 애플리케이션의 사례는 많다.

FP는 불변성과 공유 상태를 엄격하게 통제므로 멀티스레드 프로그램도 보다 직관적으로 작성할 수 있다.


주어진 인자만 잘 활용한다(외부 상태에 의존하지 마라 => 내부에서 갑자기 생기는 값들(ex. db query result?))

개발자들은 절차적, 함수형, 객체지향형 접근 방법이 들어 있는 손가방에서 적절히 골라 섞어 쓰면 된다.

왜 하필 자바스크립트일까?

편재성(어디에나 있음)

자바 스크립트의 함수는 중 주요 작업단위 로서 애플리케이션에게 할 일을 시키는 역할뿐만 아니라 객체정의, 모듈 생성, 이벤트 처리 등의 책임도 맡는다.

진짜 함수형 자바스크립트 코드는 흔치 않다.

함수형 프로그래밍은 호출자로부터 데이터를 숨길 필요 없이 소규모의, 아주 단순한 자료형만을 대상으로 움직인다.

만사가 불변이니 얼마든지 객체를 직접 만지작거려도 된다.

한마디로 데이터와 기능을 느슨하게 결합하는것 => 객체지향은 객체의 데이터와 나누니 기능이 단단히 유착되어 응집도가 높은 패키지가 형성됨

OOP는 메서드에 상속 계층을 두고 데이터를 서로 단단히 묶는 일에 열중한다. 이와 달리 함수형 프로그래밍은 다양한 자료형을 아우르는 일반적인 다형성 함수를 선호하며 this 는 가급적 사용하지 않는다.

불변성을 바탕으로 사고하려면 사실상 모든 객체를 값으로 취급해야한다.

FP는 불변성을 강하게 요구한다!

모든 객체에 불변성을 가지기는 어렵기 때문에 새 객체를 만드는 정책을 적용하면 큰 도움이 된다.

개발자가 직접 카피 온라이트 전략으로 메서드를 호출 하는것도 방법이지만 에러나기 쉽상!

판박이 코드로 도배하지 않고 은밀하게 상태적 객체를 불변 상태로 바꿀 수 있는 묘안이 렌즈, 또는 함수형 레퍼런스 자료형의 속성에 접근하여 불변화하는 함수형 프로그래밍 기법 => 람다Js

FP에서 함수는 수학책에 나오는 함수처럼(null이나 undefined가 아닌) 사용 가능한 결과 를 낼 경우에만 유의미하며, 그 외에는 외부 데이터 변경 등의 부수효과를 일으킨다고 볼 수 있다.

자바 스크립트 함수는 일급이라서 일단 변수에 할당한 뒤 나중에 실행해도 된다!

애플리케이션의 흐름

프로그램이 정답에 이르기까지 거치는 경로를 제어흐름이라고 한다.

명령형 프로그램은 분기, 루프에 따라 움직이는 일련의 연산(구문)들로 구성된다.

반면 함수형 프로그램은 독립적인 블랙박스 연산들이 단순하게, 즉 최소한의 제어 구조를 통해 연결되어 추상화 수준이 높다.

함수형 프로그램은 서로 연결된 블랙박스 연산을 제어한다. 한연산에서 다른연산으로 독립적으로 흘러가며 반복은 상당부분 줄이거나 없애고 고수준의 추상화로 대체한다.

연산을 체이닝하면 간결하면서 물 흐르는 듯한, 표현적인 형태로 프로그램을 작성할 수 있다.

메서드 체이닝

메서드 체이닝은 여러 메서드를 단일 구문으로 호출하는 OOP 패턴이다. 불변객체에 많이 적용되는 패턴인데,

함수형에도 잘 맞다? 함수형에서 객체변이는 금지되어 있는데 어떻게 그럴까?

역시나 함수형의 중요한점은 원본 객체를 바꾸지 않아야한다는것.

개별함수가 하는일은 보잘것 없지만, 함께 뭉치면 복잡한 작업도 척척 해낼 수 있다.

함수형 프로그래밍에따른 프로그램이란 순수함수들을 평가하는 과정이라고 볼 수 있다.

재귀는 변이가 없다. 사실상 순수 함수형 언어는 모든 루프를 재귀로 수행하기 때문에 기본 루프 체계조차 없다.

함수의 파이프라인은 입력과 출력이 서로 호환돼야한다.

함수를 합성하려면 반드시 부수효과를 없애야 한다. 순수함수로 작성한 프로그램은 그 자체로 순수한 프로그램으로, 시스템의 다른 부분을 손대지 않아도 더 복잡한 프로그램의 일부로 합성할 수 있다.

명령형 에러처리의 문제점

자바스크립트 코드에서 에러가나는 상황은 다양하다. 애플리케이션/서버 간 통신이 끊기거나, Null 속성에 접근하려고 할때도 나지만, 간혹 서드파티 라이브러리 함수도 예외를 던져 특수한 에러 조건을 알린다. 개발자는 소 잃고 외양간 고치기 전에 늘 최악의 상황, 즉 실패 케이스를 마음속으로 대비해야한다.

함수형 프로그래밍은 예외를 던지지 않는다. => 예기치 않게 스택이 풀리게되면 함수호출 범위를 벗어나 시스템에 영향을 미치는 부수효과를 일으킨다.

null check라는 고질병

Leave a comment