12
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[JavaScript] reduceは可読性が悪くループで置き換え可能なので使わないようにしている話

Last updated at Posted at 2020-08-18

reduceは使いこなすのが難しい?

reduceを見ても、なんだこりゃ?という感じで、使うのが難しいなと思っていました。

なので、自分が reduce を使いこなせないとよいプログラマではなく、reduce を使いこなすのがよいプログラマなのか?と感じたこともありました。

で、下記のような話を目にしました。

なぜGuidoはmap() やfilter(),reduce() そしてlambdaをPython 3から取り除きたかったのですか? - Quora

Pythonの作成者であるGuido van Rossumは、関数型プログラミングがあまり好きではありません。このことは周知の事実です。

Guido:「私は現実世界でのコードの読みやすさと有用性を重視しています。map()とfilter()が適切な場合もいくつかありますが、他のケースではPythonのリスト内包表記があるのです。わたしがreduce()を嫌いになったのは、それを使うとほとんど常に「(a)sum()を実装するのにしか使われていない」「(b)読み取り不可能なコードになってしまう」ということからです。

Python作成者の方はとても天才の部類にはいる方だと思いますが、その人でも難しいというか、読み取り不可能なコードになるということをすっぱりと見抜いていたのですね。

私は Python についてはよく知らないのですが、リンク先記事でのGuido氏の判断は見事だと思います。

JavaScriptではsumは組み込み関数ではないですが、関数化してしまえばいいわけですし、sumをreduceではかけなくてもループなら簡単に書けます。そして、sumする以外の場面でreduceが有効な場面はあまりありません。

reduceはループ回数が読み取りにくい

MDNで紹介されている非常に簡単なサンプルです。
Array.prototype.reduce() - JavaScript | MDN

const array1 = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;

// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
// expected output: 10

// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(reducer, 5));
// expected output: 15

初見でreducerが何回実行されるのか、を知るのはかなりわかりにくいです。この例では配列の個数が固定なのでわかりやすいかもしれませんが、現実のコードでは配列長は変化することが多いのでコードの読み取りはより複雑になります。

reduceの第二引数の有無によってreducerの実行回数が変わり、currentValueが何回目のreducerの実行によって呼び出されるのかが変わるというコードはかなり読みにくいです。第ニ引数は必ず指定するべき、という自分ルールをつけておいた方がよいかもしれません。

reduce は簡単にループで置き換え可能

reduceを使わなくてもおそらく全ての場面においてループ処理で記載でき、そのほうが読みやすいので、わざわざreduceを使う必要がまずありません。

関数型的な、array.forEachや、array.map、array.filter、array.find、array.findIndex、これらは使いやすく直感的なので私はよくつかいます。なので、関数型的なコードを否定するわけではないです。

その関数型プログラミング的なものの中でも、reduce は圧倒的に使いにくく読みにくく、置き換え可能なので使う必要がないだろうと思っています。reduce は forEach, for ,for of などで置き換え可能です。そして置き換えたほうが可読性があがり、修正も機能拡張も高いだろうと思います。

他の人にも読みやすいコードがよい

forではなくreduceを使って「こんな新しい構文使いこなせる俺すげー」的な記事を、両手の指の数くらいは見てきたと思います。ループでは数行かかるけど、reduce使えば1行で短いぜ、みたいな記事も多いです。

for は変数間違いを引き起こしやすいという点があるので避ける理由があるにせよ forEach や、for of は多くのプログラマが慣れているので十分読みやすく、reduceは慣れてないプログラマには結構読むのが苦労する場面もあるでしょう。

数行を減らして可読性を落としている気がするのでもったいないなと思います。
プログラムは書くよりも読む方がむずかしく、少しでも読みにくいコードになると、そしてそれが大量に積み重なると不具合を見抜くのが少しずつ少しずつ難しくなり潜在的に不具合の温床になっていくことがあります。

業界がより効率化するためにも、シンプルなことをシンプルに実装する、読みやすいコード書く人が増えて欲しいと思います。

12
7
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?