프로그래머들은 reduce를 싫어한다, 코드 리뷰에서 자주 지적받는 이유
- 블로그 작성자는 코드 리뷰에서 map과 filter를 쓴 부분에는 지적을 거의 받지 않았지만 reduce를 쓰면 "이 부분은 읽기 어렵다"는 피드백을 자주 받았다고 밝힘
- reduce가 덜 인기 있는 이유로 읽기 어려움, 낯섦, 더 나쁠 수 있는 성능, 자바스크립트·파이썬·스위프트에서의 덜한 우아함을 추측으로 제시하고, 클로주 개발자였던 시절에는 이런 피드백을 받지 않았다고 덧붙임
- 해커뉴스 최상위 댓글은 명령형 언어에서 reduce가
for item in collection루프보다 나을 게 없다고 지적함. map과 filter는 결과의 성질을 바로 알 수 있지만 reduce는 결과가 무엇이든 될 수 있음 - 댓글에서는 같은 연산이 reduce·fold·accumulate로 이름이 여러 개인 점, 람다 두 개를 받는 어색한 시그니처, 파이썬에서 sum·min·max·any·all로 대부분 대체되는 점이 언급됨
- 스파크 데이터프레임을 합칠 때
reduce(DataFrame.union, list_of_dfs)가 for 루프보다 낫다는 실무 사례와, 누적 변수에 한 글자나 부적절한 이름을 붙이는 관행이 가독성을 망친다는 지적도 나옴
Hacker News opinions
명령형 언어에서 reduce는 for 루프보다 나은 게 없음. map과 filter는 결과가 원본과 같은 길이인지, 원소를 그대로 쓰는지 바로 알 수 있는데 reduce는 결과가 뭐든 될 수 있고 부작용도 가능함. 그냥 문법만 나쁜 루프임.
그런 고차 함수를 인자로 받는 API라면 부작용이 없어야 한다는 계약을 문서에 명시해야 함. 자바 Stream#reduce는 accumulator가 associative, non-interfering, stateless라고 적혀 있음.
reduce가 덜 인기 있는 건 람다를 두 개 받아서임. 부분 결과 초기화를 건너뛰고 람다를 읽은 다음 다시 돌아와야 해서 읽는 흐름이 끊김. awk처럼 BEGIN/END 블록이 있으면 훨씬 낫겠음.
accumulate, fold, reduce로 이름이 서너 개씩 있는 게 배울 게 많아 보이게 만듦. fold에 익숙한 사람도 reduce를 만나면 한 번 더 생각하게 됨. map과 filter는 이렇게 이름이 많지 않음.
fold는 선형이고 reduce는 결합 법칙과 항등원, 즉 모노이드가 필요하다는 미묘한 차이도 있음. 아무 데나 갖다 쓰면 안 되는 이유임.
스파크 데이터프레임을 합칠 때는 reduce(DataFrame.union, list_of_dfs)가 for 루프보다 훨씬 나음. 우리 팀은 함수형 싫어하는 개발자들인데도 이건 다들 잘 씀.
파이썬에서는 reduce가 거의 필요 없음. sum으로 대부분 해결되고 start 값만 바꾸면 되고, 읽기도 쉽고 빠르고 import도 필요 없음. 곱셈이면 numpy를 쓰게 되어 있음.
수치 코드에서는 einops.reduce가 numpy나 pytorch의 sum보다 읽기 좋음. 이름 붙은 차원으로 리덕션할 수 있어서 축 인덱스를 매번 다시 따져볼 필요가 없음.
문제는 누적 변수 이름을 대충 짓는 관행임. 한 글자짜리도 많고, 심하게는 동료가 cum이라고 지어놔서 정말 곤란했음.
이름 자체가 헷갈림. 몇 달에 한 번 만나면 좋은 기능이네 하고 넘어가고, 그 뒤로는 있는 줄도 모르고 안 씀.
데이터 차원을 줄이니까 reduce임. 2d에서 1d로, 1d에서 0d 스칼라로 줄어듦.
map, filter, reduce는 함수형 삼총사이고 MapReduce의 절반임.
가장 저수준 배열 함수라서 그럼. 나머지는 전부 reduce로 쓸 수 있지만 반대는 안 되니까 덜 친절한 게 당연함.
원칙적으로는 reduce를 좋아함. 다만 실무에서는 로컬 가변 상태를 쓰는 루프나 이터레이터가 머리를 덜 씀. 함수형이 명령형보다 어려운 전형적인 사례임.
인자 두 개와 반환값이 같은 타입이고 항등원이 있을 때, 예를 들어 ADD나 MAX, CONCAT에 reduce가 잘 맞음. 모노이드가 reduce와 어떻게 맞물리는지 다룬 글을 추천함.
나는 reduce를 좋아하는데 다른 사람들이 이렇게 싫어하는 줄은 몰랐음.
작성자가 말하는 건 fold임. fold는 컬렉션을 단일 값으로 바꾸는 가장 쉽고 편한 방법이고, 나는 반대쪽에 속함.