core: multi-collection map handles nil elements in a lazy-seq input (jolt-dzh)

The multi-coll map step detected end-of-seq with (nil? (ls-first cur)), which
also fired on a legitimate nil element — so mapping over a lazy-seq containing
nils truncated at the first nil. That's why (doall (map merge a b)) collapsed to
() as a reduce accumulator. Use seq-done? to detect exhaustion and push the value
(which may be nil). doall is unchanged; clojure.data restored to the canonical
(doall (map ...)) form. Conformance 218/218; battery 3919.
This commit is contained in:
Yogthos 2026-06-06 19:28:47 -04:00
parent e623968b45
commit bfb49f23ab
2 changed files with 13 additions and 13 deletions

View file

@ -44,15 +44,12 @@
"Diff associative things a and b, comparing only keys in ks." "Diff associative things a and b, comparing only keys in ks."
[a b ks] [a b ks]
(reduce (reduce
;; mapv (eager) rather than the reference's (doall (map …)): jolt's (fn [diff1 diff2] (doall (map merge diff1 diff2)))
;; multi-collection map is lazy and doesn't force reliably as a reduce
;; accumulator here.
(fn [diff1 diff2] (mapv merge diff1 diff2))
[nil nil nil] [nil nil nil]
(mapv (partial diff-associative-key a b) ks))) (map (partial diff-associative-key a b) ks)))
(defn- diff-sequential [a b] (defn- diff-sequential [a b]
(vec (mapv vectorize (diff-associative (vec (map vectorize (diff-associative
(if (vector? a) a (vec a)) (if (vector? a) a (vec a))
(if (vector? b) b (vec b)) (if (vector? b) b (vec b))
(range (max (count a) (count b))))))) (range (max (count a) (count b)))))))

View file

@ -834,12 +834,15 @@
(while (< i (length cs)) (while (< i (length cs))
(let [cur (in cs i) ridx (in idxs i) real (in reals i)] (let [cur (in cs i) ridx (in idxs i) real (in reals i)]
(if (not (nil? cur)) (if (not (nil? cur))
(let [val (ls-first cur)] # Detect exhaustion with seq-done?, NOT (nil? (ls-first)): a
(if (nil? val) (do (set ok false) (break)) # lazy-seq can legitimately contain nil elements, and treating the
(do (array/push args val) # first nil as end-of-seq truncates (e.g. mapping over a previous
# map result that holds nils).
(if (seq-done? cur) (do (set ok false) (break))
(do (array/push args (ls-first cur))
(put next-cs i (ls-rest cur)) (put next-cs i (ls-rest cur))
(put next-idxs i (+ ridx 1)) (put next-idxs i (+ ridx 1))
(put next-reals i nil)))) (put next-reals i nil)))
(let [c (if (nil? real) (let [c (if (nil? real)
(let [rc (realize-for-iteration (in colls i))] (let [rc (realize-for-iteration (in colls i))]
(put next-reals i rc) rc) (put next-reals i rc) rc)