diff --git a/lib/ocaml/runtime.sx b/lib/ocaml/runtime.sx index 28e101a7..3d754646 100644 --- a/lib/ocaml/runtime.sx +++ b/lib/ocaml/runtime.sx @@ -157,6 +157,47 @@ end let stable_sort = sort + + let rec combine xs ys = + match xs with + | [] -> (match ys with + | [] -> [] + | _ -> failwith \"List.combine: unequal lengths\") + | hx :: tx -> + match ys with + | [] -> failwith \"List.combine: unequal lengths\" + | hy :: ty -> (hx, hy) :: combine tx ty + + let rec split lst = + match lst with + | [] -> ([], []) + | (a, b) :: t -> + (match split t with + | (xs, ys) -> (a :: xs, b :: ys)) + + let rec fold_left2 f acc xs ys = + match xs with + | [] -> (match ys with [] -> acc | _ -> failwith \"List.fold_left2: unequal\") + | hx :: tx -> + match ys with + | [] -> failwith \"List.fold_left2: unequal\" + | hy :: ty -> fold_left2 f (f acc hx hy) tx ty + + let rec iter2 f xs ys = + match xs with + | [] -> (match ys with [] -> () | _ -> failwith \"List.iter2: unequal\") + | hx :: tx -> + match ys with + | [] -> failwith \"List.iter2: unequal\" + | hy :: ty -> f hx hy; iter2 f tx ty + + let rec map2 f xs ys = + match xs with + | [] -> (match ys with [] -> [] | _ -> failwith \"List.map2: unequal\") + | hx :: tx -> + match ys with + | [] -> failwith \"List.map2: unequal\" + | hy :: ty -> f hx hy :: map2 f tx ty end ;; module Option = struct diff --git a/lib/ocaml/test.sh b/lib/ocaml/test.sh index 4a6ad7b0..23c0d5d1 100755 --- a/lib/ocaml/test.sh +++ b/lib/ocaml/test.sh @@ -900,6 +900,16 @@ cat > "$TMPFILE" << 'EPOCHS' (epoch 2105) (eval "(ocaml-type-of-program \"let rec fact n = if n = 0 then 1 else n * fact (n - 1);; fact 5\")") +;; ── More List functions: combine/split/iter2/fold_left2/map2 ── +(epoch 2200) +(eval "(ocaml-run \"List.combine [1;2;3] [\\\"a\\\";\\\"b\\\";\\\"c\\\"]\")") +(epoch 2201) +(eval "(ocaml-run \"List.split [(1,\\\"a\\\");(2,\\\"b\\\")]\")") +(epoch 2202) +(eval "(ocaml-run \"List.fold_left2 (fun a b c -> a + b + c) 0 [1;2;3] [10;20;30]\")") +(epoch 2203) +(eval "(ocaml-run \"List.map2 (fun a b -> a + b) [1;2;3] [10;20;30]\")") + EPOCHS OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>/dev/null) @@ -1423,6 +1433,12 @@ check 2103 "shape -> Int" '"shape -> Int"' check 2104 "program x+y" '"Int"' check 2105 "program fact 5" '"Int"' +# ── More List functions ───────────────────────────────────────── +check 2200 "List.combine" '("tuple" 3 "c")' +check 2201 "List.split" '("tuple" (1 2) ("a" "b"))' +check 2202 "List.fold_left2" '66' +check 2203 "List.map2" '(11 22 33)' + TOTAL=$((PASS + FAIL)) if [ $FAIL -eq 0 ]; then echo "ok $PASS/$TOTAL OCaml-on-SX tests passed" diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index 6a279534..1abc3ab5 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -250,7 +250,8 @@ SX CEK evaluator (both JS and OCaml hosts) `append`, `iter`, `for_all`, `exists`, `mem`, `nth`, `hd`, `tl`, `rev_append`, `concat`/`flatten`, `init`, `iteri`, `mapi`, `find`, `find_opt`, `assoc`, `assoc_opt`, `partition`, `sort`, - `stable_sort` (insertion sort, O(n²)). _(Pending: combine, split.)_ + `stable_sort`, `combine`, `split`, `iter2`, `fold_left2`, `map2`. + 30+ functions covered. - [~] `Option`: `map`, `bind`, `value`, `get`, `is_none`, `is_some`, `iter`, `fold`, `to_list`. _(Pending: join/to_result.)_ - [~] `Result`: `map`, `bind`, `is_ok`, `is_error`, `get_ok`, @@ -372,6 +373,10 @@ the "mother tongue" closure: OCaml → SX → OCaml. This means: _Newest first._ +- 2026-05-08 Phase 6 — List.combine/split/iter2/fold_left2/map2 (+4 + tests, 367 total). Mechanical pair-walk OCaml implementations, + failwith on length-mismatch matching Stdlib semantics. List module + now covers 30+ functions. - 2026-05-08 Phase 5.1 — baseline expanded to 8 programs (8/8 pass). Added: closures.ml (curried adders), quicksort.ml (recursive sort on lists), exception_handle.ml (exception decl + raise + try/with).