Data-first HO forms, fix plan pages, aser error handling (1080/1080)
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled

Evaluator: data-first higher-order forms — ho-swap-args auto-detects
(map coll fn) vs (map fn coll), both work. Threading + HO: (-> data
(map fn)) dispatches through CEK HO machinery via quoted-value splice.
17 new tests in test-cek-advanced.sx.

Fix plan pages: add mother-language, isolated-evaluator, rust-wasm-host
to page-functions.sx plan() — were in defpage but missing from URL router.

Aser error handling: pages.py now catches EvalError separately, renders
visible error banner instead of silently sending empty content. All
except blocks include traceback in logs.

Scope primitives: register collect!/collected/clear-collected!/emitted/
emit!/context in shared/sx/primitives.py so hand-written _aser can
resolve them (fixes ~cssx/flush expansion failure).

New test file: shared/sx/tests/test_aser_errors.py — 19 pytest tests
for error propagation through all aser control flow forms.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-15 18:05:00 +00:00
parent bdbf594bc8
commit 3a268e7277
10 changed files with 615 additions and 51 deletions

View File

@@ -598,3 +598,100 @@
n
(+ (fib (- n 1)) (fib (- n 2))))))
(fib 7))"))))
;; --------------------------------------------------------------------------
;; 8. Data-first higher-order forms
;; --------------------------------------------------------------------------
(defsuite "data-first-ho"
(deftest "map — data-first arg order"
(assert-equal (list 2 4 6)
(map (list 1 2 3) (fn (x) (* x 2)))))
(deftest "filter — data-first arg order"
(assert-equal (list 3 4 5)
(filter (list 1 2 3 4 5) (fn (x) (> x 2)))))
(deftest "reduce — data-first arg order"
(assert-equal 10
(reduce (list 1 2 3 4) + 0)))
(deftest "some — data-first arg order"
(assert-true
(some (list 1 2 3) (fn (x) (> x 2))))
(assert-false
(some (list 1 2 3) (fn (x) (> x 5)))))
(deftest "every? — data-first arg order"
(assert-true
(every? (list 2 4 6) (fn (x) (> x 1))))
(assert-false
(every? (list 2 4 6) (fn (x) (> x 3)))))
(deftest "for-each — data-first arg order"
(let ((acc (list)))
(for-each (list 10 20 30)
(fn (x) (set! acc (append acc (list x)))))
(assert-equal (list 10 20 30) acc)))
(deftest "map-indexed — data-first arg order"
(assert-equal (list "0:a" "1:b" "2:c")
(map-indexed (list "a" "b" "c")
(fn (i v) (str i ":" v)))))
(deftest "fn-first still works — map"
(assert-equal (list 2 4 6)
(map (fn (x) (* x 2)) (list 1 2 3))))
(deftest "fn-first still works — reduce"
(assert-equal 10
(reduce + 0 (list 1 2 3 4)))))
;; --------------------------------------------------------------------------
;; 9. Threading with HO forms
;; --------------------------------------------------------------------------
(defsuite "thread-ho"
(deftest "-> map"
(assert-equal (list 2 4 6)
(-> (list 1 2 3) (map (fn (x) (* x 2))))))
(deftest "-> filter"
(assert-equal (list 3 4 5)
(-> (list 1 2 3 4 5) (filter (fn (x) (> x 2))))))
(deftest "-> filter then map pipeline"
(assert-equal (list 30 40 50)
(-> (list 1 2 3 4 5)
(filter (fn (x) (> x 2)))
(map (fn (x) (* x 10))))))
(deftest "-> reduce"
(assert-equal 15
(-> (list 1 2 3 4 5) (reduce + 0))))
(deftest "-> map then reduce"
(assert-equal 12
(-> (list 1 2 3)
(map (fn (x) (* x 2)))
(reduce + 0))))
(deftest "-> some"
(assert-true
(-> (list 1 2 3) (some (fn (x) (> x 2)))))
(assert-false
(-> (list 1 2 3) (some (fn (x) (> x 5))))))
(deftest "-> every?"
(assert-true
(-> (list 2 4 6) (every? (fn (x) (> x 1))))))
(deftest "-> full pipeline: map filter reduce"
;; Double each, keep > 4, sum
(assert-equal 24
(-> (list 1 2 3 4 5)
(map (fn (x) (* x 2)))
(filter (fn (x) (> x 4)))
(reduce + 0)))))