From f776de378fae65c5d517cb253691399bf1eb0943 Mon Sep 17 00:00:00 2001 From: Martino Ferrari Date: Wed, 24 Jun 2026 10:57:45 +0200 Subject: [PATCH] fix(logic): single-eval array index + typed reduce accumulators - Fix redundant double-evaluation of n.a in the 'index' case by extracting to a local const before use in both idx() call and array indexing. - Add explicit type argument to reduce() calls in sum and mean functions to fix TypeScript TS2345 accumulator type error: the inferred ArrVal union type was not compatible with numeric addition. Co-Authored-By: Claude Opus 4.6 --- web/src/lib/expr.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/web/src/lib/expr.ts b/web/src/lib/expr.ts index fc990db..10dc0b4 100644 --- a/web/src/lib/expr.ts +++ b/web/src/lib/expr.ts @@ -229,8 +229,8 @@ function idx(i: number, len: number): number { const ARR_FUNCS: Record ArrVal> = { len: a => asArr(a[0]).length, - sum: a => asArr(a[0]).reduce((s, x) => s + asNum(x), 0), - mean: a => { const r = asArr(a[0]); return r.length ? r.reduce((s, x) => s + asNum(x), 0) / r.length : 0; }, + sum: a => asArr(a[0]).reduce((s, x) => s + asNum(x), 0), + mean: a => { const r = asArr(a[0]); return r.length ? r.reduce((s, x) => s + asNum(x), 0) / r.length : 0; }, // min/max: scalar-variadic OR single-array — see ev() dispatch below slice: a => { const r = asArr(a[0]); const s = a[1] === undefined ? 0 : asNum(a[1]); const e = a[2] === undefined ? r.length : asNum(a[2]); return r.slice(s, e); }, concat: a => asArr(a[0]).concat(asArr(a[1])), @@ -256,7 +256,10 @@ function ev(n: Node, R: Resolver): ArrVal { case 'arr': return n.items.map(it => ev(it, R)); case 'sig': return R(n.ds, n.name); case 'var': return R('local', n.name); - case 'index': return asArr(ev(n.a, R))[idx(asNum(ev(n.i, R)), asArr(ev(n.a, R)).length)]; + case 'index': { + const arr = asArr(ev(n.a, R)); + return arr[idx(asNum(ev(n.i, R)), arr.length)]; + } case 'un': return n.op === '-' ? -asNum(ev(n.a, R)) : (asNum(ev(n.a, R)) === 0 ? 1 : 0); case 'tern': return asNum(ev(n.c, R)) !== 0 ? ev(n.a, R) : ev(n.b, R); case 'call': {