[오라일리] 함수형 프로그래밍 with 자바

“한빛미디어 <나는 리뷰어다> 활동을 위해서 책을 제공받아 작성된 서평입니다.”

자바를 처음 접한 게 대학 2학년 때였던 것 같다. 아주 핫한 언어였고, C/C++ 언어의 단점을 극복한 언어라면서 홍보도 많이 했었다. 컴파일러 성능을 개선하기 위한 논문이 쏟아졌고, 한 번에 처리할 인자 수를 늘리면서 성능이 대폭 개선됐다는 얘기도 들려왔다.

실제 취직을 해서 웹 프로그래밍을 하게 되었을 때도 핫했던 Servlet/JSP 기술을 도입해서 만들어내느라 바빴다. 그만큼 자바는 산업계에 큰 파장을 일으켰다.

그런데 어느 순간부터 자바가 자바스럽지 않게 되면서, 수많은 산업계의 요구사항이 빗발치면서 자바가 변했다. 그 변화를 따라잡는 게 쉽지 않아졌다. 심지어 선에서 오라클로 주도권이 바뀌기도 했다.

잠깐 한 눈을 팔고 돌아와보니 내가 알던 자바는 완전 구닥다리처럼 변해 있었다. JVM에서 돌아가는 다른 언어를 익히고 나니, 자바 코딩이 너무 힘들어졌다. 스칼라는 객지지향 언어와 함수형 언어의 장점을 혼합한 언어였고, 러닝 커브가 거셌지만, 한 번 익히고 나니 그 간결함과 대폭 줄어든 코드량에 열광했다. 다만, val과 var의 차이점과, 과거 자바스럽게 코딩하던 버릇 때문에 적응이 어려웠다. 하지만 그 지점을 통과하고 나니 val만 쓰는 방식이 너무 편하다. 문제가 발생해도 값을 인식하지 못한 지점에서 바꾸는 상황이 없어지니 디버깅 하기도 수월해졌다.

그런데 회사에서 스칼라를 버리고 자바로 가게 됐다. 그나마 최신 트렌드로 무장한 코틀린으로 가고자 했지만, 자바를 익힌 개발자들의 저항이 거셌다. 결국 현실적인 이유 때문에 코틀린으로 가지 못하고 자바로 회귀했다.

가만 생각해보면, 자바가 과연 문제일까? 자바가 문제가 아니라, 자바식으로 코드를 작성하는 게 부담스럽다. 무엇 때문에? 막대한 코드량 때문이다. 최신 트렌드가 반영된 언어들과 자바로 같은 로직을 작성해보면, 그 양이 현격히 차이가 난다. 그래서 코드를 읽는 게 부담스럽기도 하고 로직이 먼저 보이는 게 아니라, 로직을 짜기 위해 필요한 코드들이 방해했다.

뭔가 해결책이 필요했다. 그것이 자바 8 이후로 전격 도입된 함수형 프로그래밍 지원이었다. 처음에는 그런 코드들도 너무 군더더기가 많다고 생각했는데, 이 책을 읽으면서 이유를 알게 됐다. 바로 하위 호환성 때문이었다는 것. 새로 도입하는 거라면 과감하게, 최신 트렌드처럼, 간결하게 만들어도 됐을 텐데, 하위 호환 가능하도록 만들다보니 어쩔 수 없이 취해야 했던 모양새다.

도입은 했는데, 이걸 내가 제대로 알고 쓰는 게 맞을까? 놓치고 있는 건 얼마나 될까? 사실 이걸 반영하기 위해 상용 IDE가 제안하는 도구들을 활용해서 조금씩 반영하곤 있었다. 하지만 이게 맞는 걸까? 그런 고민으로 부담감이 날로 커지는 가운데, 이 책을 만나게 됐다.

정말 내가 필요로 했던 책이다. 그런데 단순히 개념만 설명하는 책은 아니었다. PART 01 함수형 기초를 읽을 때까지는 매우 고통스러웠다. 익숙하지 않은 전문용어가 많이 나왔다. 기술 용어? 아니다, 수학적 개념을 이해해야 하는 용어들이다. 번역하는 사람 입장에서도 힘들었겠다 싶었다. 지지부진하게 읽다가, 슬슬 속도가 붙기 시작한 지점이 record 설명할 때였다. 그나마 최신 언어에서 실험 중인 기능을 조금 써 봤다. 그러다보니 설명을 이해하는 게 많은 도움이 됐다.

자바 람다에 대해선 피상적으로만 쓰고 있었는데, 확실하게 알게 되었던 건 큰 수확이다. 물론 정말로 잘 이해했고, 잘 활용하려면 기존 코드를 변경하고 비교해가면서 확고히 하는 수밖에 없겠지만, 그냥 모르는 채로 대충 쓰는 것과는 확실히 다르다. 빨리 적용해보고 싶을 지경이다.

함수형 인터페이스 Function, Consumer, Supplier, Predicate 이것들은 알게 모르게 쓰고는 있었는데, 이제야 뭔지 알 것 같다. 역시 연습을 통해 확실하게 익혀둬야겠다.

스트림 역시 마찬가지다. 스칼라에서 쓰던 형태 비슷하게 쓰고 싶어서 쓰기 시작했던 건데, 코드를 정리하기 위해서라도 더 많이 쓰려고 한다. 내가 관리하는 시스템은 성능보다는 명확한 로직과 의도, 유연한 추가나 변경이 더 중요한 시스템이다. 성능이 중요하지 않다기보다는, 지장이 없을 정도면 되고, 오히려 다양한 요구사항을 빠른 시간 안에, 안정적으로 제공해주는 게 더 중요하다. 게다가 권한도 명확해야 하고, 변화에 대한 기록도 분명하게 해줘야 하는 거다보니 더욱 명확하게 파악해야 한다. 그런 면에서 함수형 도입은 분명히 필요하다.

리팩토링을 하려고 하는 코드는 전형적인 과거 자바 스타일 코드들이다. 솔직히 로직이 안 보인다. 너무나 많은 예외 처리들이 존재한다. 좀더 객체지향적으로 구조 개선을 하든가, 한 눈에 보이도록 함수형으로 개선하던가 해야 한다. 그런 면에서는 개인적으로 함수형이 더 나은 것 같다. 객체지향은 좋긴 한데, 뭔가 명확하게 흐름을 파악하기에는 문제가 많은 것 같다. 물론 설계 미스였겠지만.

인상깊은 부분은 스칼라의 try/success/failure를 함수형으로 구현한 부분이었다. 솔직히 왜 나는 이런 부분을 생각하지 않았을까 싶었고, 스칼라가 해당 기능을 JVM에서 돌리기 위해 비슷한 형태로 내부 구현한 게 아닐까 하는 생각마저 들었다. 물론 이게 진실이라고 생각진 않는다. 이 부분은 실제 구현된 부분을 확인해봐야 알 수 있는 내용이겠지만.

제일 많이 쓰고자 하는 건 역시나 Optional이다. 너무 명확해서 뭐라 말하기가 어렵다. 이걸 쓰고 안 쓰고는 확실히 차이가 나는 게, 정신이 아찔할 정도로 if 절을 남발할 수밖에 없는 상황을 반전시킬 수 있는 키 피처 중 하나다. 스트림과 Optional, 이 둘만 적절히 정리해줘도 지금보다는 확실히 낫다.

느긋한 계산법 (지연 평가), 이걸 제대로 몰랐던 건데, 설명을 아주 잘 해준다. 게다가 저자가 다년 간 일하면서 알게 된 주옥같은 가이드나 팁, 경험 공유는 무척이나 값지다. 기술 설명하는 것보다, 이런 내용들이 오히려 저자가 하고 싶었던 내용이 아닌가 싶다.

재귀 부분은 일반적으로 아는 정도로만 알고 있었는데, 새로운 관점을 알게 해줬다. 눈이 번쩍했다.

함수형 디자인 패턴과 자바를 위한 함수형 접근 방식은 한 번만 읽어서는 안 될 내용이다. 이 내용은 여러 번 읽어서 전달하고자 하는 내용을 체화해야 할 것들이다. 단순한 내용도 아니고 쉬운 내용도 아니다. 이것들을 내것으로 만들 수만 있어도 한 번의 빅 점프를 할 수 있다는 생각이 들었다.

저자는 독학으로 개발자가 되었다고 했다. 본인은 전산학을 전공했지만, 솔직히 저자만큼의 지식을 쌓았다는 생각이 들지 않는다. 역시 배움에는 끝이 없고, 읽어야 할 책은 매년 쏟아져 나온다. 그래서 할 일은 전혀 줄지 않았다. 그래서 흥미로운 세계가 바로 프로그래밍이 아닐까?