1장, 왜

2021.12.20

  • 문법은 한낱 세부사항일뿐이다. 어려운 점은 바로 다른 방식으로 사고하는 법을 배우는 것이다.
  • 함수형으로 코드를 짜는 것은 설계 트레이드오프, 재사용할 수 있는 여러 빌딩블록, 그리고 다른 여러 가지의 통찰력과 연결된다.

1.1 패러다임 전환

  • 컴퓨터 과학은 단속적으로 발전한다. 수십 년 전의 훌륭한 아이디어가 어느날 갑자기 주류에 포함되곤 하는 식이다.
    • 자바는 초창기에 느리고 메모리를 과하게 사용해서 고성능 어플리케이션용으로는 적합하지 않다고 여겨졌지만, 하드웨어 시장의 변화로 선호도가 높아졌다.
  • 함수형 프로그래밍은 객체지향과 개념적으로 같은 궤도를 따른다.
    • 지난 이삼십 년간 학계에서 연구되었고, 현대 프로그래밍 언어들에 조금씩 도입되어왔다.
  • 우선 전통적인 프로그래밍 스타일(명령형 루프)과 좀 더 함수형 방법으로 같은 문제를 대조해보면서 시작해보자.

텍스트 파일을 읽고, 가장 많이 사용된 단어들을 찾고, 그 단어들과 빈도를 정렬된 목록으로 출력하라.

1반복문 {
2  const lowercaseWord = word.toLowercase();
3  if (!NON_WORDS.contains(lowercaseWord)) {
4    if (!wordMap.has(lowercaseWord)) {
5      wordMap.set(lowercaseWord, 1)
6    } else {
7      wordMap.set(lowercaseWord, wordMap.get(lowercaseWord) + 1)
8    }
9  }
10}
1배열.map((w) => w.toLowercase())
2  .filter((w) => !NON_WORDS.contains(w))
3  .forEach((w) => wordMap.set(lowercaseWord, (wordMap.get(lowercaseWord) || 0) + 1));
  • 첫번째 예제는 세 연산(소문자, 비 단어 검출, 단어 빈도수 카운팅)을 한 번의 반복자 블럭에서 실행함으로써 성능명료함과 맞바꾸었다.
  • 이는 보편화된 트레이드오프지만 책의 저자는 별로 권장하지 않는다.
  • 클로저를 만든 리치 히키(Rich Hickey)는 Strange Loop 콘퍼런스 기조연설 단순함이 쉬움을 낳는다에서 컴플렉트(complect)란 고어를 사용했다.
  • 함수형 프로그래밍에서는 map, filter와 같은 고계함수를 통해 추상화의 단계를 높여 문제를 더욱 명료하게 볼 수 있다.

1.2 언어 트렌드에 발 맞추기

  • 주요 언어들이 변화하는 것을 보면 모두 함수형 기능을 더하고 있다.
  • 이런 패러다임을 배우면, 새 언어를 쓰든 지금 사용하는 언어를 계속 쓰든, 함수형 기능들이 도입되자마자 사용할 수 있게 된다.

1.3 언어/런타임에 제어를 양도하기

  • 고수준의 추상화를 통해 복잡한 비즈니스 문제를 풀 궁리를 하지, 까다로운 저수준 문제는 더 이상 생각하지 말자.
  • malloc에 시달리기엔 인생은 너무 짧다.
  • 자바가 메모리 관리 작업을 쉽게 해줬다면, 함수형 프로그래밍 언어는 다른 빌딩블록들을 고수준 추상적 개념으로 대체해준다.

1.4 간결함

  • 레거시 코드 활용 전략의 저자인 마이클 페더스는 함수형과 객체지향형 추상화의 차이에 대해 아래와 같이 말하였다.

    객체지향 프로그래밍은 움직이는 부분을 캡슐화하여 코드 이해를 돕고, 함수형 프로그래밍은 움직이는 부분을 최소화하여 코드 이해를 돕는다.

  • OOP의 세계에서는 고유한 자료구조를 작성하는 것을 권하고, 특정 동작을 메서드의 형태로 부착한다.
  • 함수형 언어는 가변(Mutable) 상태를 제어하는 메커니즘을 구축하기보다, 그런 움직이는 부분을 아예 제거하는 데 주력한다.
    • 언어가 오류가 발생하기 쉬운 기능을 적게 노출하면 개발자가 오류를 만들 가능성이 줄어든다는 이론에 따른 것이다.
  • 함수 수준의 캡슐화는, 모든 문제에 대한 새로운 클래스 구조를 구축하는 것보다 세분화되고 기초적인 수준에서 재사용을 가능하게 한다.