diff --git a/builtin/core.wren b/builtin/core.wren index 5baf4e5b..dc8a9888 100644 --- a/builtin/core.wren +++ b/builtin/core.wren @@ -29,7 +29,18 @@ class Sequence { return acc } - reduce(f) { this[1..-1].reduce(this[0], f) } + reduce(f) { + var iter = iterate(null) + if (!iter) Fiber.abort("Can't reduce an empty sequence.") + + // Seed with the first element. + var result = iteratorValue(iter) + while (iter = iterate(iter)) { + result = f.call(result, iteratorValue(iter)) + } + + return result + } } diff --git a/src/wren_core.c b/src/wren_core.c index 8699d4d8..71762347 100644 --- a/src/wren_core.c +++ b/src/wren_core.c @@ -72,7 +72,18 @@ static const char* libSource = " return acc\n" " }\n" "\n" -" reduce(f) { this[1..-1].reduce(this[0], f) }\n" +" reduce(f) {\n" +" var iter = iterate(null)\n" +" if (!iter) Fiber.abort(\"Can't reduce an empty sequence.\")\n" +"\n" +" // Seed with the first element.\n" +" var result = iteratorValue(iter)\n" +" while (iter = iterate(iter)) {\n" +" result = f.call(result, iteratorValue(iter))\n" +" }\n" +"\n" +" return result\n" +" }\n" "\n" "}\n" "\n" diff --git a/test/list/reduce_single_item.wren b/test/list/reduce_single_item.wren index 195778f4..0f874c99 100644 --- a/test/list/reduce_single_item.wren +++ b/test/list/reduce_single_item.wren @@ -1 +1,2 @@ -[1].reduce {|a, b| a } // expect runtime error: Range start out of bounds. +IO.print([1].reduce {|a, b| 42 }) // expect: 1 +IO.print([].reduce(1) {|a, b| 42 }) // expect: 1