Skip to content

TASK: Audit existing LAMBDAs for array-lifting support #179

@jimmytacks

Description

@jimmytacks

Origin

Synced from Notion: TASK: Audit existing LAMBDAs for array-lifting support

Content

Problem

Several existing LAMBDAs in the library silently produce wrong results when given array/range inputs instead of scalars. They don't error — they return a single mixed-up value, which is hard to spot and hard to debug. Confirmed: CELLTOPOS(D6:E6) returns 3300017 (a value derived from row of arg 1 + column of arg 2 mashed together) instead of {3300017, 5500028}.

Root cause: bodies use functions that consume an array as a whole (SUMPRODUCT, SEQUENCE(LEN(x)), multi-capture REGEXEXTRACT, etc.) on parameters that may themselves be arrays. The lambda gets called once with the entire array and the aggregator collapses or mis-aligns the cross-product.

For competitive cases this is a silent footgun — you'll reach for a helper, point it at a column, and get a plausible-but-wrong number with the clock running.

Rule for what should lift

  • Should lift: any LAMBDA with at least one scalar-shaped input and a scalar-shaped output. Lifting is per-parameter (a parameter that semantically takes one value).
  • Can't lift (skip): LAMBDAs with no real inputs (constant-table helpers), or whose output is inherently an array (region/window extractors).

Scope

Review every LAMBDA currently in the library:

  • CELLTOPOS, POSTOCELL — coordinate conversion
  • MOVECELL, ARROWMOVES, DEFAULTARROWS, DEFAULTMOVEDELTAS, KNIGHTDELTAS — grid movement
  • GRIDAREA, GRIDLOOKUP — grid extraction/lookup
  • INCEL — INDIRECT shorthand
  • (plus any others added between now and execution)

For each, classify as:

  1. Already lifts — pure element-wise body, no action
  2. ⚠️ Doesn't lift but should — needs upgrading
  3. Skip — no scalar input (constant helpers) or array output (region extractors)

Approach

Apply the dispatcher pattern (proven working on CELLTOPOS_FIXED):

=LAMBDA(arg, [opts],
  IF(OR(ROWS(arg)>1, COLUMNS(arg)>1),
     MAP(arg, LAMBDA(v, FUNCNAME_SCALAR(v, opts))),
     FUNCNAME_SCALAR(arg, opts)))

Keep the original scalar body as <NAME>_SCALAR (workbook-private helper) and have the public name dispatch. Non-breaking for existing scalar callers; new behaviour for range inputs. The dispatcher must come after the ISOMITTED(...) → ShowHelp branch so =CELLTOPOS() still returns help text.

For LAMBDAs with multiple array-eligible parameters (e.g. MOVECELL(cell, dir)), decide per-function whether to:

  • Lift over just the primary arg (simpler, covers most uses)
  • Lift over the cartesian product (more powerful, more complex)
  • Require equal-shape arrays and zip them (often what's actually wanted)

Initial classification

LAMBDA Category Notes
CELLTOPOS ⚠️ Upgrade SUMPRODUCT(... SEQUENCE(LEN(letters)) ...) collapses array of cell refs
POSTOCELL ⚠️ Verify + upgrade Uses ADDRESS which doesn't lift cleanly across arrays in all builds
MOVECELL ⚠️ Upgrade Calls CELLTOPOS internally — may inherit fix; verify after CELLTOPOS upgraded
GRIDLOOKUP ⚠️ Upgrade Calls CELLTOPOS; value→address branch needs check
INCEL ⚠️ Upgrade INDIRECT doesn't lift over arrays of addresses
GRIDAREA ➖ Skip Output is inherently a rectangular array — can't lift
DEFAULTARROWS ➖ Skip No real input; constant table
DEFAULTMOVEDELTAS ➖ Skip No real input; constant table
KNIGHTDELTAS ➖ Skip No real input; constant table
ARROWMOVES ➖ Skip HSTACK of two constant tables

Deliverable

  • Each upgraded LAMBDA replaces the existing definition (same name, same parameter signature, same scalar behaviour)
  • A small test sheet in the workbook (or saved snippet) proving each handles {single, array} inputs correctly
  • Help text updated to note array support

Notes

  • Watch for circular issues: if CELLTOPOS is upgraded first, MOVECELL / GRIDLOOKUP / GRIDAREA may inherit the fix for free in their scalar bodies (since they call CELLTOPOS on a single value). Audit downstream usages before adding redundant dispatchers.
  • The investigation that surfaced this is in Book3 / Sheet1 (rows 20–116 are the test grid and findings; rows 121–124 demonstrate the dispatcher pattern working on CELLTOPOS_FIXED).
  • Don't break the help-text mechanism (ISOMITTED + ShowHelp).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or improvementlambda-ideaLAMBDA function idea for the backlogstatus: doneCompleted

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions