함수형 반응형 프로그래밍 - FRP 입문자를 위한 종합 안내서

1. 필요와 충분의 사이에서

듣기(listening)을 멈추고 반응(reacting)을 시작하라! p.29

한동안 python으로 작업하는 일이 많았고, 프레임워크의 절대적인 도움을 많이 받다보니 요즘 힙(hip)하다는 ‘함수형’ 프로그래밍을 소문으로만 들었지 프로덕션에 적용해 볼 수 있는 기회가 없었다. 짧게 말해서, 함수형 프로그래밍을 해 본적이 전혀 없었다. 그리고 해야(should, would) 할 이유도 없었기 때문에 신경을 쓰지 않고 있었다.

그런데, 올해(2017) 5월부터 미국에 있는 팀과 협업을 하는 과정에서 JDK 8을 기반으로한 Spring Boot를 사용하게 되면서 람다(lambda)stream()을 사용하게 되면서 함수형 프로그래밍 언어를 배워야(must) 할 이유가 생겼다.

그래서 서점에 가서 책을 몇권 구매해서 읽기 시작했다. 제일 처음 읽기 시작한게 자바 8 인 액션, 이였다. 나의 소중한 JDK 6에 비해서, JDK 8은 천지개벽같은 상황이었다. 소중한 나의 JDK 6은 이제 안녕을 고하고 JDK 8을 열심히 사용하려고 했지만, JDK 8에 포함된 각 종 개념들 덕분에 코드가 슬프게 되어버렸다.

일은 해야했기 떄문에 끙끙거리면서 코드를 작성하긴 했지만 뭔가 애매한 코드만 잔뜩 작성한 듯 싶다. 그래서 Rx계열의 책을 구매해서 읽어도 보고, 함수형 프로그래밍과 관련된 서적들을 조금씩 읽어보았지만, 다른 책에서 언급해서 알고 있을 것 같은 내용의 전혀 모르는 개념들만 머리속에 뒤죽박죽 되었다. 그래도 계속해서 읽고, 남는 시간에 예제를 수정하고 변경해 보는 작업을 계속해서 진행했다.

5월부터 시작된 나의 ‘JDK 8’과 함수형의 탐구는 끝나지 않았다. 이번에 운이 좋겠도 한빛미디어에서 책을 지원받을 수 있게 되었을 때, [함수형 반응형 프로그래밍 - FRP 입문자를 위한 종합 안내서]가 눈에 들어왔고, 젭싸게 선택했다.

함수형 반응형 프로그래밍

2. 쉽지만 어려운 ‘생각의 전환’

FRP는 새로운 패러다임이다. […] 여러분이 그 사고방식을 받아들인다면 FRP를 가장 잘 활용할 수 있다. p.48

이 책을 선택했던 이유는 지금까지 읽었던 몇 권의 책을 정리해 줄 것 같은 매력적인 이름 때문이기도 하지만, 함수형반응형을 공부할 때 참고하던 블로그1에서 이 책을 언급2한것이 기억났기 때문이다.

책을 받고 두근두근 하는 마음으로 읽었기 시작했다. 이전에 읽었던 책에 비해서 함수형에 대한 정의, 반응형과의 차이점에 대해서 꼼꼼하게 소개해주기 때문에 이전에 내가 읽었던 책의 내용을 가볍게 상기할 수 있었고, 함수반응에 대해서 나름의 기준을 가질 수 있어서 굉장히 좋았다. 특히 번역이 잘되어 있어서 읽는데 거부감이 없다는 점도 좋았다.

가볍운 예제를 통해서 Sodium의 사용법을 알려주는 부분에서 역시나 약간은 어렵고 조금은 뜬구름 잡는 느낌이 들었다. 그럼에도 불구하고 내용 자체가 어렵지 않았기 때문에 조금씩 읽어나가자 이 책의 백미라 할 수 있는 4장까지 간신히 올 수 있었다.

3. 예제!, 예제가 좋다!

FRP는 근본적으로 출력을 입력의 측면에서 선언적으로 기술하는 것이다. p.56

이 책은 예제가 굉장히 좋다. 챕터 4의 경우 약 40페이지에 걸쳐서 주유 펌프 예제를 진행하게 된다. 이 예제는 Sodium 라이브러리를 사용해서 함수형 프로그램밍 기법을 사용해서 진행된다. 주유 펌프 로직을 구현하는 인터페이스부터 선언해서 주유 펌퍼의 키패드까지 코딩을 진행할 수 있다. 4챕터에서 진행되는 주유 펌프 예제는 책 전반에 걸쳐서 가장 재미있고, 유익했던 부분이다. 함수형 프로그래밍 기법만 사용해서 만들어지는 예제기 때문에 코드를 최대한 많이 수정했고, 내가 알고 있는 개념들을 하나씩 코드로 연습해 볼 수 있었기 때문에 이 챕터를 오랫동안 읽었다.

또한 11챕터에 가면 함수형 프로그래밍 기법을 사용해서 I/O, 프라미스/퓨처, 분산처리 등을 연습해 볼 수 있기 때문에 앞선 챕터에서 이론적인 설명을 코드를 사용해서 실행해 볼 수 있다.

4. 결론

[…] FRP는 발견이지 발명이 아니다. […] 여러분이 선호하는 언어의 FRP 라이브러리가 없다면 기존의 구현을 그 언어로 포팅할 것을 권한다. p.40

이 책은 단점보다 장점이 많은 책이다. 아주 훌륭한 예제를 인터페이스 선언부터 키패드 클래스를 구현하는 부분까지 상세하게 다루고 있기 때문에 함수형 프로그래밍 기법을 손쉽게 연습해 볼 수 있으며, 함수형반응형에 관한 두 가지 논의를 한 권의 책을 통해서 읽을 수 있다.

반면, 기존의 함수형 프로그래밍 기법을 소개하는 책이나 반응형 라이브러리인 RxJavaRxJS를 설명하는 책 혹은 분산처리 라이브러리인 Akka를 다루는 책에 비해서 학술적인 설명 혹은 원론적인 설명이 부족할 수 있으며, 특정 라이브러리에 지나치게 의존한다는 단점이 있을 수 있다.

장점과 단점을 고려했을 때, 함수형 프로그램이 기법이나 반응형 라이브러리와 관련된 선수 지식이 있으신 분들에게 적극적으로 추천하고, 이러한 프로그래밍 기법이나 라이브러리를 처음 접하는 분들에겐 4장의 예제를 중심으로 공부하고, 자신에게 필요한 부분의 전문적인 서적을 참고해보시면 좋을 듯 싶다.

함수형 반응형 프로그래밍


  1. 엥겔바트의 시스템은 경천동지할 만큼 놀라운 상호작용성을 보여줬다. […] 데스크톱이라는 용어와 사용자 인터페이스 면에서의 여러혁신과 더블어 그 시스템에는 최초의 객체지향 언어인 스몰토크가 탑재되어 있었다. p.5

  2. […] 비동기 시스템을 프로그래밍하면서 다양한 문제로 어려움을 겪어본 프로그래머라면 FRP나 Rx가 크게 도움 될 수 있다. 이 책은 개발자라면 누구나 읽어볼 만한 가치가 있는 책이라고 감히 말하고 싶다. p.9

  3. “질문자가 구현이 아니라 명세에 대해 먼저 물어본 것이 기쁩니다. […] 많은 친구들이 이 두 가지(표시적, 시간 연속적)를 빼먹고 여러 가지 구현상의 관념만으로 FRP를 정의하곤 합니다. 내가 볼 때 그런 정의는 모두 요점을 벗어난 것입니다. p.32

  4. 마이크로소프트의 반응형 확장은 이 책을 쓰는 현재 진정한 FRP가 아니다. Rx는 아카와 FRP 중간의 어느 지점에 위치한다. Rx와 FRP의 설계 목표에는 차이가 있다. Rx는 주로 이벤트 핸들러를 사슬처럼 엮는데 관심이 있으며 다양하게 엮는 방법을 제공한다. p.34

  5. […] 스레드는 상태 변화를 제어 흐름으로 모델링한다. 스레드는 상태 변화 순서가 명확히 정의될 때 I/O에 잘 어울리는 경향이 있다. 액터나 제너레이터도 이 범주에 넣을 수 있는다. 이벤트는 프로그램에서 전파되는 이산적이고 비동기적인 메시지다. 이벤트는 순서가 덜 명확할 때 적합하다. 특히, 구성요소 간의 상호작용이 복잡할 때 잘 들어맞는다. 전형적인 응용으로는 그래픽 사용자 인터페이스와 비디오 게임을 들 수 있다. p.35

  6. Unit은 일종의 ‘아무것도 아닌 값’이다. Unit은 함수형 프로그래밍 용어이자 개념이다. […] 값이 없는 경우 하나뿐인 인자에 채워 넣을 아무것도 아닌 값이 하나 필요하다. p.65

  7. 다시 반복하지만 FRP의 기본 연산에 전달되는 함수는 모두 다 반드시 참조 투명(또는 순수)해야 한다. 이는 그 함수가 I/O를 수행하거나, 외부 상태를 읽거나, 외부 상태를 변경하거나, 내부 상태를 유지해서는 안 된다는 뜻이다. p.86

  8. 람다를 입력으로 받는 메서드가 여러분을 대신해서 자원을 열고 닫는 경우를 ‘빌려쓰기 패턴’이라 한다. 파일을 사용할 때 이런 패턴을 자주 볼 수 있다. p.95

  9. […] 그런 경우 언어의 설계(포인터)로 인해 컴파일러가 프로그램의 시간적인 메모리 접근 패턴을 인식해서 최적의 위치에 투명하게 각 메모리 블럭을 배치하는 것이 불가능하다. p.158

  10. 모든 문제를 합성적인 방법을 사용해서 다룰 수 있는 것은 아니다. 상태가 있는 이벤트 기반의 로직은 언제나 비합성적인 분류에 들어가며 그런 문제는 항상 버거의 온상이다. p.166

  11. 여러분이 항상 불변 데이터 구조를 사용해야 한다는 것은 참조 투명성에 따른 자연스러운 귀결이다. […] 이런 데이터 구조를 함수형 데이터 구조나 영속적 데이터 구조라고 부른다. p.172

  12. […] 이 10가지 연산을 함께 사용하면 모든 것이 멋지고 조화로운 완벽한 세상이 탄생한다. p.257

  13. 액터는 단일 비동기 입력 대기열을 통해서 들어오는 메시지를 처리하는 임무를 가지는 프로세스다. […] 액터는 주로 스레드와 같은 제어 흐름을 사용해 구현된다. p.307

  14. […] 결과적으로 여러분은 거의 아무것도 없는 데서 스트림을 만든 셈이다. 우리는 이를 스파크라고 부른다. p.338

  15. […] FRP는 타입 주도 개발이라 할 수 있다. FRP에서 데이터 타입은 문제를 제한하고 여러분이 실수를 저지를 가능성을 낮춰준다. FRP에서 타입의 역할은 TDD에서 테스트의 역할과 비슷하다. 하지만 TDD에 비해 노력은 더 적게 든다. p.343


Written on August 25, 2017