Feat/runner array length#476
Closed
cukas wants to merge 3 commits into
Closed
Conversation
The discriminating oracle for the array `.length` read slice, authored BEFORE the impl so the runner change is built to this spec. RED-at-base: the certify cases abstain today (the `member` case admits only a caught-error `.message`); they turn green only when the runner reads array length. The fences already pass (abstaining is the correct fail-close at base). - packages/core/tests/runner-array-length.test.ts (new) — direct ReferenceRunner spec: 6 certify cases (count / empty-0 / nested TOP-LEVEL count / arithmetic flow / scalar bind / parenthesized receiver) + 14 fail-close fences (string, ASTRAL string, number, boolean, rebound, array-literal receiver, index-position receiver, chained member, non-`length` member, optional, computed, unbound, and two direct evalPortableValue checks). - packages/python/tests/kern-run-cli-differential.test.ts — 4 `.length` CERT entries (count / empty / nested top-count / arithmetic), every byte verified on real node + python3 via the emitter probe. - packages/cli/tests/run.test.ts — CLI exit-code contract: `.length` happy (count / empty / arithmetic, exit 0) + abstain (string / astral / optional / computed / non-`length` member, exit 2). Module doc updated. Only ARRAY `.length` certifies: a STRING receiver abstains because JS `.length` counts UTF-16 code units while Python `len()` counts code points — `"😀".length` is 2 in JS, 1 in Python (verified). Reference-only — the emitters already lower a portable array `.length` to `len(...)` (Python) / `.length` (TS). ⚔️ Forged by [Agon](https://github.com/KERNlang/agon) Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
The ReferenceRunner — the executor `kern run` uses — now READS an array's
ELEMENT COUNT, so a program can ask how big an array is natively:
let xs = [1,2,3] -> print xs.length -> 3
This continues the array slices (2a literal binding + each, 2b literal index).
An array branch is added to the `member` case of `evalPortableValue`, BEFORE the
caught-error `.message` handling and behind the SAME fences: a `.length` read
certifies ONLY as a non-optional `.length` on a BARE IDENTIFIER bound to a
portable array, and returns the element count — a non-negative safe integer.
Everything else throws -> the runner ABSTAINS.
Only ARRAYS certify. A STRING `.length` must NOT: JS `.length` counts UTF-16
code units while Python `len()` counts code points, so `"😀".length` is 2 in JS
and 1 in Python (verified on real node + python3). `Array.isArray` excludes
strings, numbers, booleans, decimals, and caught errors, so every non-array
receiver falls through and abstains. Non-ident receivers (`[1,2,3].length`,
`xs[0].length`, `xs.length.foo`), optional (`xs?.length`), computed
(`xs['length']`), a non-`length` member (`xs.foo`), rebound, and unbound idents
all abstain too.
Reference-only change: an abstaining program is never certified and never
reaches the emitter differential. The emitters ALREADY lower a portable array
`.length` to `len(...)` (Python) / `.length` (TS), so no codegen change is
needed; the 3-leg differential passes as-authored. The length value is an
ordinary safe integer, so it flows through arithmetic / comparison / binding /
print with no further hazard. `evalPortableValue` is internal to the
ir/semantics runner layer (not re-exported), so `.length` extends only the
runner's scalar contexts (print / if / while / fmt / assign), consistently
fenced.
The slice-2a `.length access abstains (deferred)` fence is updated to assert a
STRING `.length` abstains (array `.length` now certifies) — mirroring how
slice-2b relaxed slice-2a's in-bounds index fence.
Gate: array-length spec 20/20 + array-values 13/13 + array-index 25/25 +
runner-entry-import-graph + ir-semantics neighborhood 164/164 + CLI run.test
52/52 + 3-leg differential 23/23 (0 skipped) + biome + docs:contracts:check.
Planned with agon brainstorm; built by codex via agon conquer against the
RED-at-base oracle; reviewed by the full agon roster.
⚔️ Forged by [Agon](https://github.com/KERNlang/agon)
Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
…fence coverage
Full-roster agon review (4 engines clean; kimi 2 important + nits). Triaged:
- [important 0.90] Member case lacked a hasBinding check (unlike the sibling
index case), so an UNBOUND receiver failed with the generic "outside portable
scalar domain" instead of a precise "binding not found". Still abstained either
way — diagnostics, not soundness — but now consistent with the index case.
- [important 0.60] Parenthesized-receiver test "may not match parser" — REFUTED:
`parseExpression("(xs).length")` yields a member on a bare ident (verified) and
the test is green; it documents real, sound certifying behavior. Kept.
- nits adopted: NULL and DECIMAL (tagged-object) receiver fences added, a
nested-array TOP-LEVEL-count CLI happy test added, and the direct-helper test
renamed from "abstains" to "throws" (abstain is runner-level terminology).
Gate: array-length 24/24 + array-values 13/13 + array-index 25/25 + CLI 53/53 +
biome. No behavior change to certified output; abstain outcomes unchanged.
⚔️ Forged by [Agon](https://github.com/KERNlang/agon)
Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
9702c00 to
4c039cb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Why
How
Checklist
tsc -bpassespnpm testpassespnpm test:kernpassespnpm lintpasseskern review packages/ --recursivechecked