手続き型と関数型のコード比較が卑怯

https://kentutorialbook.github.io/functionalprogramming2022/
手続き型であれば以下のコードが……

let sum = 0;
let x = 0;

for (let i = 0; i < 10; i++) {
  x = x + 1;
  sum = sum + x;
}

console.log(sum);

関数型だと、こうなります。

const add = (a, b) => a + b;
const sum = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].reduce(add);

console.log(sum);

関数型は素晴らしい。
……という主張は卑怯である。
まず関数型サンプルで「1, 2, 3, 4, 5, 6, 7, 8, 9, 10」をベタに書いてあるのは手続き型と等価なコードとは言えない。
そして関数型サンプルは「reduce」というシステム側で用意されたロジックを使っている点がフェアではない。
この比較をフェアに行うならば、関数型サンプルコードは以下のようなものになるべきだろう。

const add = (a, b) => a + b;
const range = (min, max) => ( min == max ? [min] : [min, ...range(min+1, max)] );
const reduce = (ls, f, acc) => ( ls.length == 0 ? acc : f(reduce(ls.slice(0, -1), f, acc), ls[ls.length-1]) );
const sum = reduce(range(1, 10), add, 0);
console.log(sum);
// ※sliceは配列操作なので「ロジック」ではないという前提で書いている。実際haskellではx:xsのような文法として取り込まれているので。

もちろんこれは揚げ足取りでしかなく関数型の本質的なメリットはいささか減りはしないが、ちょっと不当なコード比較になっているんじゃないか?と思った。



わざわざreduceを定義している上の例は逆に関数型言語に不利な気もする。
フェアなのはこっちか?

const total = (ls) => ( ls.length == 0 ? 0 : ls[0] + total(ls.slice(1)) );
const range = (min, max) => ( min == max ? [min] : [min, ...range(min+1, max)] );
const sum = total(range(1, 10));
console.log(sum);