多くのソフトウェア開発環境において、コレクションを単一の値に集約するための多用途なツールである'reduce'関数の使用は、コードレビュー中に否定的なフィードバックを引き起こすことがよくあります。開発者が'map'や'filter'をほとんど精査されることなく頻繁に使用する一方で、'reduce'は「読みづらい」あるいは対になる関数よりもエレガントではないと指摘されることが多々あります。
'Reduce'回避の社会的現象
Evan Hahn氏は、自身が'map'や'filter'を絶えず使用しても同僚から苦情を受けることはない一方で、'reduce'の使用は頻繁に「コードが読みづらい」というフィードバックに繋がると報告しています。彼は、これがJavaScript、Python、Swiftなどの言語において、'reduce'がそれほど馴染みがない、あるいは読みづらい、またはエレガントではないことが原因である可能性を示唆しています。
Hahn氏は、この傾向が技術的な失敗というよりも社会的な現象である可能性があると指摘していますが、Clojureのような関数型プログラミングの環境では、このようなフィードバックは大幅に少なくなることも認めています。彼は、自身が'reduce'を好む場合であっても、コードレビュープロセスの社会的期待を満たすために、しばしば他のメソッドに戻ることを観察しています。
認知負荷と推論パターン
Hacker Newsのコメント欄では、'map'や'filter'が好まれる理由は、単一要素の出力が他の要素から独立しているため、ローカルな推論が可能だからであると主張されました。対照的に、'reduce'(または'fold')は、コレクション全体を通じて進化するアキュムレータの状態について、開発者にグローバルな推論を強いることになります。
あるコメント投稿者は、'reduce'は関連する型に対してゼロ値や初期状態を「思い出す」ことを要求するため、精神的なオーバーヘッドを追加すると指摘しました。他の人々は、命令型言語において'reduce'は標準的な'for'ループよりもほとんど利点を提供しないことが多く、より複雑な構文を導入するだけであり、「より悪い構文のループ」であると指摘しました。
不一致と実装のトレードオフ
'reduce'にとっての大きな障害は、プログラミング言語間での一貫性の欠如です。コメント投稿者は、コールバック内でのアキュムレータが第1引数か第2引数か、あるいは関数が初期値を受け取るかどうかが言語によって異なることに言及しました。この不一致により、初期値を提供しない場合に空のコレクションがクラッシュを引き起こす可能性があるため、'reduce'は「足元を掘る(footgun)」ツールとなります。
議論では、Python内での'reduce'関数による文字列結合のO(n^2)複雑性など、パフォーマンスのリスクも強調されました。あるコメント投稿者は、Python 3において'reduce'がライブラリ関数に格下げされた歴史的な逸話を共有しました。それは、二次時間複雑性によってスレッドプールを使い果たした行の折り返しアルゴリズムに関連する本番環境のインシデントを引き起こしたためでした。
最小権限の原則
「最小権限の原則」は、より高レベルな抽象化を好む理由として引用されています。'reduce'は非常に強力で汎用的であるため、技術的にはほぼすべてのコレクション変換を達成できますが、すでに専用の、より読みやすい関数が存在するパターンを再実装するために誤用されることがよくあります。
複数のコメント投稿者の共通認識は、'map'や'filter'のような高レベルな操作が十分に柔軟でない場合は、すべてを一度に行うために'reduce'に頼るよりも、操作を複数の単純なステップに分解するか、伝統的なループを使用する方が良いことが多いということです。
不確実性と主観的な好み
'reduce'に対する「嫌悪」の証拠は、プロフェッショナルなコードレビューにおいてこれらの苦情の頻度を測定するための定量的なデータが提供されていないため、大部分が逸話的なものにとどまっています。さらに、「正しい」選択は、特定の言語や、開発者が関数型プログラミングの概念にどの程度精通しているかに依存することが多いです。
一部の開発者は、'reduce'を複雑なロジックを呼び出し元から遠ざけることで簡素化する「ハンマーと釘」のような手法であると考える一方で、他の人々は、リダクションがどのように実行されるかの透明性が欠如しているため、'map'や'filter'よりも安全な抽象化ではないと主張しています。
