現状の実装では、アロー関数で `return` を省略した場合の返却値について、ライブラリ関数と JavaScript で書いた関数の扱いに、微妙な差異が生じているようです。

例です。よくある、配列から最大値を探す処理をアロー関数で書きました。


[ 1, 5, 3, 8, 6 ].reduce((x, y) => Math.max(x, y), -Infinity);

返却値は `8` です。正しく動いています。

ふと気付きます。普通の関数型言語では、こういう場合、アロー関数なしで機能するはず…。


[ 1, 5, 3, 8, 6 ].reduce(Math.max, -Infinity);

返却値は `NaN` です。あれ? だめなんかい…。おそらく `Math.max` が計算結果ではなく `undefined` を返しているのでしょう。

さらに閃きます。`max` を自前で書いたらどうなる?


const max = (x, y) => x > y ? x : y;
[ 1, 5, 3, 8, 6 ].reduce(max, -Infinity);

返却値は `8` です。関数の型(`Number * Number -> Number`)としては同じだと思いますが、ライブラリ関数は NG で、自前で書いたものは OK ですね…。

なお、reduce を自前で書いてもうまくいきます。


function reduce (array, fn, initial) {
  let r = initial;
  for (let i = 0; i < array.length; i++) {
    r = fn(r, array[i]);
  }
  return r;
}

reduce([ 1, 5, 3, 8, 6 ], Math.max, -Infinity);

ES6 非サポートの環境でも同様の結果になります。どうも昔からあるバグのように見えます。