erlang: lists foldr/3 + partition/2 + takewhile/dropwhile/splitwith (823/823)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m5s

Higher-order traversal family in lib/erlang/lists-ext.sx, registered
pure via the er-register-builtin-bifs! wrapper. foldr right-folds;
partition returns {Yes,No} order-preserved; splitwith = {takewhile,
dropwhile}. lists_ext suite 38 -> 52.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-30 13:34:44 +00:00
parent 343c508939
commit 42a16f7cf3
5 changed files with 134 additions and 6 deletions

View File

@@ -159,6 +159,8 @@ The Phase 9 opcodes are registered, tested, and bridged SX↔OCaml, but inert: n
_Newest first._
- **2026-06-30 stdlib hardening — `lists` higher-order traversal** — Added `foldr/3`, `partition/2`, `takewhile/2`, `dropwhile/2`, `splitwith/2` to `lib/erlang/lists-ext.sx`, registered pure through the `er-register-builtin-bifs!` wrapper (consistent with the existing pure `map`/`filter`/`foldl`). `foldr` right-folds (order-preserving when consing); `partition` returns `{Satisfying, NotSatisfying}` order-preserved via `er-list-reverse-iter`; `splitwith` = `{takewhile, dropwhile}`. `lists_ext` suite 38→**52** (+14). Conformance **809 → 823/823**. loops/erlang only.
- **2026-06-30 stdlib hardening — `lists` keylists** — Added the keylist family to `lib/erlang/lists-ext.sx`: `keyfind/3`, `keymember/3`, `keydelete/3`, `keyreplace/4`, `keystore/4`, `keytake/3`, `keysort/2`. All operate on lists of tuples keyed on element N (1-indexed), act on the first match only, and pass through non-tuples / tuples shorter than N. Key comparison is `==` (`er-equal?`) per the stdlib; `keysort/2` reuses the stable `er-ext-msort` + `er-ext-lt?` from the sort commit, comparing extracted keys. `keytake/3` returns `{value, Tuple, Rest}` / `false`. Registered through the same `er-register-builtin-bifs!` wrapper so they survive registry resets. `lists_ext` suite 17→**38** (+21: hit/miss/first-match-only/short-tuple-skip across all seven, keysort by elem 1 and 2 + stability). Conformance **788 → 809/809**. Test-harness note: `element(2, T)` returns an integer (no `:name`), so those two cases compare the raw number via `erlang-eval-ast` rather than `er-lx-nm`. loops/erlang only.
- **2026-06-30 stdlib hardening — `lists:sort/1,2` + `lists:usort/1`** — Roadmap is saturated within this loop's scope (every remaining `[ ]` is blocked: `httpc`/`sqlite` on absent host primitives, 10a/10c on out-of-scope `lib/compiler.sx`). Continued as forever-loop hardening by filling idiomatic-Erlang stdlib gaps. Added the `lists` sort family in a **new file `lib/erlang/lists-ext.sx`** (loaded after `runtime.sx`): stable merge sort over an SX-list bridge, registered via `er-register-pure-bif!`. `lists:sort/1` and `usort/1` use full Erlang term order; `sort/2` takes a `fun(A,B)->bool` comparator. **Two notable findings:** (1) the shared `er-lt?` (transpile.sx) only deep-compares numbers/atoms/strings and treats *any two tuples (or lists) as order-equal* — so `lists:sort` (and, latently, `min/2`/`max/2`) would not order compound terms. Fixed locally with a self-contained `er-ext-lt?` that compares tuples by arity-then-elementwise and lists elementwise (shorter proper prefix first), delegating cross-type cases to `er-lt?`. `er-lt?` itself left untouched (shared by the `<` operator; can't edit transpile.sx — see Blockers). (2) `tests/runtime.sx` resets the BIF registry mid-run via `er-register-builtin-bifs!`, which would wipe a one-shot registration; so `lists-ext.sx` **wraps** `er-register-builtin-bifs!` to re-add its BIFs on every rebuild. New `lists_ext` suite (17 tests: term order, dup-keeping, stability, descending comparator, usort dedup). Conformance **771 → 788/788** (12→13 suites). New-file workaround forced because every sx-tree write tool (incl. `sx_write_file`) raises yojson "Expected string, got null" in this worktree — authored via the `Write` fallback + `sx_validate`, the same pattern other loops use. loops/erlang only.