core: Phase 5 Option A — map/filter/take/take-while always return a lazy seq
Lazy transformers now return a LazySeq even over a concrete vector, matching Clojure: (seq? (map inc [1 2 3])) is true, (vector? ...) false. Replaces the "preserve representation" eager branch (which returned a vector over vector input) by routing concrete colls through lazy-from + the lazy step machinery. Flipping these surfaced four boundary bugs, all fixed here: - cons over a lazy-seq returned a raw cell @[x thunk]; a cons-of-a-cons then treated it as a plain 2-array and leaked the rest-thunk as an element (broke interleave). cons over lazy now returns a proper LazySeq. - coll->cells mistook a user vector whose 2nd elem is a function ([first last] from juxt) for a cons cell. Cons cells are mutable arrays; user data is immutable — route pvec/plist/tuple through immutable tuples and apply the [val,fn] cell heuristic only to mutable arrays. Also coerce set/map/string/ buffer via core-seq. - ~@ splice over a lazy map result iterated a LazySeq as a Janet table (broke lazy-cat / self-ref fib). syntax-quote* now realizes via d-realize before splicing; core-sqcat (self-host) already realized. - core-next did (length r) on a lazy rest (never 0 on a table) and ls-rest could return nil → (length nil) crash. core-rest never returns nil; core-next uses seq-done? (realizes one cell). seq-done? moved above core-rest. normalize-pvecs (test helper) realizes lazy-seqs so Janet-= comparisons work. Gate: conformance 239x3 (interpret/compile/self-host, +10 Option A cases), lazy-infinite 18/18, fixpoint, self-host, all specs+unit green. (sci-bootstrap and clojure-test-suite skip — vendored dirs absent in this checkout.) Remaining for full Option A consistency (jolt-7w4): drop/map-indexed/keep/ keep-indexed/take-nth/interpose/distinct/partition/partition-all still eager over concrete input. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5e7aea70da
commit
074eb2da41
4 changed files with 127 additions and 116 deletions
|
|
@ -62,6 +62,21 @@
|
|||
["into map onto map" "{:a 1 :b 2 :c 3}" "(into {:a 1} [[:b 2] [:c 3]])"]
|
||||
["into list" "(quote (3 2 1))" "(into (list) [1 2 3])"]
|
||||
|
||||
### ---- Option A: lazy transformers return seqs, not vectors ----
|
||||
# map/filter/take/take-while over a concrete vector yield a lazy seq, matching
|
||||
# Clojure: (seq? (map ...)) is true, (vector? (map ...)) is false.
|
||||
["map vec is seq" "true" "(seq? (map inc [1 2 3]))"]
|
||||
["map vec not vector" "false" "(vector? (map inc [1 2 3]))"]
|
||||
["filter vec is seq" "true" "(seq? (filter odd? [1 2 3]))"]
|
||||
["take vec is seq" "true" "(seq? (take 2 [1 2 3]))"]
|
||||
["map over set" "true" "(= #{2 3 4} (set (map inc #{1 2 3})))"]
|
||||
["filter over map ev" "(quote ([:b 2]))" "(filter (fn [[k v]] (> v 1)) {:a 1 :b 2})"]
|
||||
# cons of cons over a lazy tail must not leak the rest-thunk
|
||||
["cons cons lazy" "(quote (1 2 3))" "(cons 1 (cons 2 (lazy-seq (cons 3 nil))))"]
|
||||
["juxt fns in vec" "[1 3]" "((juxt first last) [1 2 3])"]
|
||||
["last of lazy take" "5" "(last (take 5 (iterate inc 1)))"]
|
||||
["next empty lazy" "nil" "(next (take 1 [1]))"]
|
||||
|
||||
### ---- HIGH: destructuring ----
|
||||
["destr nested seq" "[1 2 3]" "(let [[a [b c]] [1 [2 3]]] [a b c])"]
|
||||
["destr rest+as" "[1 (quote (2 3)) [1 2 3]]" "(let [[a & r :as all] [1 2 3]] [a r all])"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue