읽은 순서랑 정리하는 순서를 맞추기가 생각보다 어렵다. 작년에 읽은 책을 이제야 정리하네. "책 제목을 꼭 이렇게 해야만 했을까?"라는 생각이 스치지만 좋은 책이다.
참고로, 이 책의 예제는 자바스크립트로 되어있는데, 리팩터링 2판과 최근에 나온 SICP 등의 특정 언어에 국한되는 내용이 아닌 책에서 예제를 구현하는 언어로 자바스크립트를 선택하고 있는데, 개발 환경을 별도로 구성할 필요도 없고 간단하게 예제를 돌려볼 수 있어서 좋다.
‘부수 효과를 없애라!’라는 슬로건 때문에 너무 단순하게 생각할 수도 있지만, 사실 함수형 프로그래밍은 부수 효과 구성에 관한 내용입니다. 부수 효과를 잘 관리해서 코드의 아무 곳에나 있지 않도록 하는 것입니다. 이 책의 주제이기도 합니다.
이 책은 보통 함수형 프로그래밍이라는 주제를 가진 책에서 등장하는 어려운 수학적 개념과 용어들을 설명에 사용하지 않으면서, 실무에 필요한 중요한 내용을 쉽게 설명해 준다. (책의 맨 마지막에 몇몇 개념과 용어에 대해 간략한 정의는 소개해 준다.)
실제 함수형 프로그래머가 액션과 계산, 데이터라는 용어를 쓰지 않을 수도 있지만 이 책에서는 그렇게 부르겠습니다.
이 책에서 말하는 액션과 계산을 오래전인 2014년도쯤에 함수형 패러다임을 도입하여 Scala와 Akka로 개발을 진행했던 프로젝트에서는 프로세서와 핸들러로 명명하고 프로세서는 상태를 가지는 I/O 처리를 담당하고 핸들러는 비즈니스 로직을 담당하면서 변수의 사용은 금지였고, 모든 연산은 불변을 기반으로 하면서 서로 책임을 완전히 분리해서 설계하고 개발을 진행했었다. 하지만, 모든 핸들러가 이 책에서 소개하는 계산처럼 완전히 상태에서 자유로운 것은 아니었고, 몇몇 핸들러는 FSM를 사용하여 상태를 관리했다. Actor를 사용하면서 데이터는 액터 메시지를 중심으로 자연스럽게 분리가 되었었다. 이 프로젝트에서 BDD도 실무에서 처음 사용했었는데, 액션과 계산 그리고 데이터가 분리되어 있으면 테스트하기가 매우 수월하다. 이게 벌써 10년쯤 전인가... 너무 재밌게 개발했던 좋은 경험으로 남아있다. 종종 생각나는 그리운 시절이다.
계층형 설계는 바로 아래 계층에 있는 함수로 현재 계층의 함수를 구현해 코드를 구성하는 기술입니다.
책이 초반은 액션과 계산을 분리하는 것에 대한 소개를 중반쯤에는 계층형 설계와 추상화의 벽이라는 개념으로 도식화하여 앞에서 설명한 개념을 더 선명하게 다이어그램과 그래프로 보여준다. 매우 직관적이라서 쉽게 이해할 수 있다.
리팩터링에 대한 내용도 소개하고 있는데 실무에서 자주 보이는 내용이고, 가성비 좋은 리팩터링이라고 생각한다.
- 암묵적 인자를 드러내기
- 함수 본문을 콜백으로 바꾸기
위 2개의 리팩터링 주제를 가지고 점진적으로 코드가 함수형 코드로 바뀌는 것을 보여주면서, 최종적으로 함수형 프로그래밍에서 흔히 보이는 map, reduce를 적용하여 정리하는 것으로 마무리한다.
서로 다른 타임라인에 있는 두 개의 콜백은 여러 가지 순서로 실행될 수 있습니다.
책 후반부에서는 비동기 환경에서 간과하기 쉬운 타이밍 이슈를 타임라인 다이어그램을 사용하여 매우 직관적으로 설명해 주면서, 동시성 기본형인 큐를 사용하여 순서를 보장하는 방법을 보여준다.
책의 마지막은 반응형과 어니언 패턴에 대한 소개로 지금까지 설명한 것들을 조합하여 조금 더 상위 레벨의 설계에 적용하는 방법을 보여준다.
조금은 유치한 제목과는 다르게 다양한 내용을 매우 유기적으로 잘 설명해 준다.
https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=296947429
액션은 시간에 의존합니다. 그래서 사용하기 가장 어렵습니다. 액션에서 시간에 의존하는 부분을 분리하면 좀 더 다루기 쉽습니다. 계산은 시간에 의존적이지 않습니다. 다루기 쉽기 때문에 가능한 코드를 계산으로 바꾸는 것이 좋습니다.
...
단순해 보이는 액션도 또 다른 액션이나 계산, 데이터로 나눌 수 있습니다. 함수형 프로그래밍에서는 액션을 더 작은 액션과 계산, 데이터로 나누고 나누는 것을 언제 멈춰야 할지 아는 것이 중요합니다.
...
계산은 입력값으로 출력값을 만드는 것입니다. 호출 시점이나 횟수에 의존하지 않고 동일한 입력값으로 부르면 항상 같은 결괏값을 돌려줍니다.
...
액션은 코드 전체로 퍼집니다. 어떤 함수 안에 액션이 하나만 있어도 그 함수 전체가 액션이 됩니다.
...
전역변수가 없어야 합니다. 전역변수를 읽는 것은 암묵적 입력이고 바꾸는 것은 암묵적 출력입니다.
...
함수에 특별한 문제가 없어도 꺼낼 것이 있다면 분리하는 것이 좋습니다. 그렇게 하면 더 좋은 설계가 됩니다.
...
언제든 최적화할 수 있습니다. 애플리케이션을 개발할 때 예상하기 힘든 병목 지점이 항상 있습니다. 그래서 성능 개선을 할 때는 보통 미리 최적화하지 말라고 합니다. 불변 데이터 구조를 사용하고 속도가 느린 부분이 있다면 그때 최적화하세요.
...
계층이 서로 구분되는 목적이 있다면, 함수가 위치할 계층을 선택하는 데 좋은 정보로 사용할 수 있습니다. 계층의 목적은 각 계층에 있는 함수의 목적과 같습니다.
...
만약을 대비해 코드를 만드는 경우가 종종 있습니다. 쓸데없는 코드는 줄이는 것이 좋습니다! 오지 않을 수도 있는 미래를 위해 불필요한 코드를 작성하는 것은 좋지 않은 습관입니다.
...
패턴을 사용하다 보면 너무 과한 추상화를 할 수 있습니다. 패턴들은 요구 사항에 맞게 적용해야 합니다.
...
각 단계에서 어떤 것을 하고 있는지 알기 쉽게 이름을 잘 지어야 합니다.
...
기억해야 할 것이 너무 많을 때 추상화 벽을 사용하면 도움이 됩니다. 추상화 벽을 사용하면 구체적인 것을 몰라도 됩니다.
...
언어에서 지원하는 스레드 모델을 이해하는 것은 중요합니다. 분산 시스템에서 어떤 부분이 순서대로 실행되고 어떤 부분이 동시에 실행되는지 이해하는 것이 중요합니다. 자원을 공유하는 부분은 버그가 발생하기 쉽습니다. 공유 자원을 확인하고 없애면 코드가 더 좋아집니다. 자원을 공유하지 않는 타임라인은 독립적으로 이해하고 실행할 수 있습니다. 따라서 함께 생각해야 할 내용이 줄어듭니다.
-알라딘 eBook <쏙쏙 들어오는 함수형 코딩> (에릭 노먼드 지음, 김은민 옮김) 중에서
'Dev' 카테고리의 다른 글
JetBrains의 IDE에서 북마크 정보 마이그레이션 (0) | 2023.05.22 |
---|---|
자바 최적화 (Optimizing Java) (0) | 2023.05.13 |
좋은 코드, 나쁜 코드 (Good Code, Bad Code) (0) | 2023.03.04 |
도메인 주도 설계 (0) | 2023.02.05 |
도메인 주도 개발 시작하기 (0) | 2023.01.09 |