map·filter는 괜찮은데 reduce는 왜 '읽기 어렵다'는 말을 들을까? 코드 리뷰 경험담

들어가며
map, filter, reduce는 함수형 프로그래밍의 3대장으로 불립니다. 그런데 이 셋 중 reduce만 유독 코드 리뷰에서 '읽기 어렵다'는 말을 자주 듣는다면 어떨까요? GeekNews에 올라온 한 개발자의 경험담이 이 질문을 던졌습니다. 이번 글에서는 이 이야기를 정리하고, 왜 이런 반응이 나오는지 함께 생각해 봅니다.
핵심 요약
- 글쓴이는 코드 리뷰에서
map,filter사용에 대한 불만은 거의 받지 않았습니다. - 반면
reduce를 쓴 패치에는 **"이 부분은 읽기 어렵다"**는 피드백을 자주 받았습니다. - 다른 사람의 코드에서도
reduce는map,filter,some보다 훨씬 드물게 보였습니다. - 여기서 글쓴이는 "프로그래머들은 상대적으로
reduce를 덜 좋아하는 것 같다"고 추측합니다. 다만 개인적인 관찰일 뿐이라고 선을 긋습니다.
코드 리뷰에서 느낀 차이
글쓴이는 평소 map과 filter를 자주 씁니다. 리뷰에서 설계 같은 다른 결정에는 피드백을 많이 받았지만, 이 두 함수를 썼다는 것 자체가 문제가 된 적은 거의 없었다고 합니다.
그런데 reduce는 달랐습니다. reduce가 들어간 코드를 올리면 리뷰어가 가독성을 문제 삼는 일이 많았다고 해요.
이해를 돕기 위해 간단한 JavaScript 예시로 비교해 보겠습니다. (원문에 있는 코드는 아니고, 에디터가 덧붙인 예시입니다.)
// map / filter: 무엇을 하는지 한눈에 보입니다
const activeNames = users
.filter(u => u.active)
.map(u => u.name);
// reduce: 같은 일을 하지만 누적값의 흐름을 따라가야 합니다
const activeNames2 = users.reduce((acc, u) => {
if (u.active) acc.push(u.name);
return acc;
}, []);
두 코드의 결과는 같습니다. 그래도 아래 코드를 이해하려면 acc가 무엇이고, 초기값이 무엇이며, 매번 무엇을 반환하는지를 머릿속으로 따라가야 합니다. 리뷰어들이 느끼는 '읽기 어려움'이 아마 여기서 오는 것이겠죠.
왜 reduce는 환영받지 못할까? 글쓴이가 꼽은 이유
글쓴이는 정확한 원인은 모르겠다며 몇 가지 가능성을 제시합니다.
- 가독성과 익숙함의 문제:
reduce는 누적값(accumulator)이라는 개념을 이해해야 해서 처음 보는 사람에게 부담이 될 수 있습니다. - 성능 문제: 경우에 따라 다른 방법보다 성능이 떨어질 수 있습니다. 예를 들어 JavaScript에서 매번 새 객체나 배열을 스프레드로 만드는
reduce는 비용이 커질 수 있습니다. - 언어별 차이: 글쓴이는 JavaScript, Python, Swift에서는
reduce가 덜 우아하게 느껴진다고 합니다. 반면 Clojure로 개발할 때는 이런 피드백을 받은 적이 없다고 해요. 함수형 언어에서는reduce가 기본 도구이다 보니 개발자들도 자연스럽게 받아들이는 것으로 보입니다. - 관찰 자체가 틀렸을 가능성: 애초에 그런 경향이 없는데 잘못 느꼈을 수도 있다고 인정합니다.
💡 참고로 Python에서는
reduce가 내장 함수가 아니라functools모듈로 옮겨졌습니다. 언어 차원에서도 리스트 컴프리헨션이나sum(),any()같은 대안을 권장하는 분위기라, 글쓴이의 느낌과도 맞닿아 있습니다.
글쓴이는 어떻게 대응했을까?
- 개인적으로는
reduce를 좋아하는 편입니다. - 그래도 리뷰에서 지적을 받으면 크게 고집하지 않고, 다른 방식으로 바꾼 뒤 넘어갔다고 합니다.
- 최근에는 이런 반응을 덜 겪는다고 해요. 다만 이유가 인식이 달라져서가 아니라 코드 리뷰가 예전보다 덜 꼼꼼해졌기 때문일지도 모른다고 봅니다.
에디터의 한마디
reduce는 강력하고 범용적인 도구입니다. 그런데 바로 그 범용성 때문에 코드만 봐서는 의도가 잘 드러나지 않는다는 약점이 있습니다. map은 '변환', filter는 '거르기', some은 '하나라도 있는지'처럼 이름만으로도 의도가 전달됩니다. 반면 reduce는 무엇이든 할 수 있어서, 결국 코드를 끝까지 읽어야 무엇을 하는지 알 수 있습니다.
그래서 실무에서는 이런 기준을 참고해 볼 만합니다.
- 합계, 최댓값처럼 단순한 집계라면
reduce나sum()같은 전용 함수를 씁니다. - 변환이나 필터링이라면
map/filter로 의도를 드러내는 것이 대체로 읽기 좋습니다. reduce가 복잡해진다면 평범한for루프가 더 명확할 수 있습니다.- 팀의 언어와 문화(Clojure 같은 함수형 언어인지 아닌지)에 따라 기준을 달리 가져가세요.
글쓴이는 마지막으로 독자들에게 이렇게 묻습니다. 비슷한 경험이 있나요? 여러분은 reduce를 좋아하시나요? 여러분 팀의 코드 리뷰에서는 reduce가 어떤 대접을 받고 있는지 한번 떠올려 보셔도 좋겠습니다.