fix nthrest empty-list semantics + if-let/when-let/if-some/when-some scoping
Two correctness bugs found while migrating: - nthrest returned nil where Clojure returns () : for n>0 the walk yields (seq xs) wrapped in (or ... ()), so an exhausted/nil walk is () not nil (only n<=0 returns coll). Both the prior Janet impl and the first overlay port got this wrong. nthrest.cljc 13/1/0 -> 14/0/0. - if-let/when-let/if-some/when-some leaked their binding into the else branch: they wrapped the whole if in (let* [name val] ...), so (let [x 5] (if-let [x nil] x x)) returned nil instead of 5. Fixed to bind a fresh temp around the if and rebind the name only inside the taken branch, matching Clojure. conformance 218/218 x3, clojure-test-suite 3928 -> 3929.
This commit is contained in:
parent
185cf30c1d
commit
f22eb660d3
2 changed files with 33 additions and 26 deletions
|
|
@ -122,13 +122,16 @@
|
|||
([f] (completing f identity))
|
||||
([f cf] (fn ([] (f)) ([x] (cf x)) ([x y] (f x y)))))
|
||||
|
||||
;; Canonical loop form: short-circuits on an empty/nil coll before examining n
|
||||
;; (so (nthrest nil n) is nil without a number check), matching Clojure.
|
||||
;; Matches Clojure exactly: n<=0 returns coll unchanged; for n>0 the walk yields
|
||||
;; (seq xs), and an exhausted/nil walk falls back to () via (or ... ()) — so
|
||||
;; (nthrest nil 100) is () (not nil), while (nthrest nil 0) is nil.
|
||||
(defn nthrest [coll n]
|
||||
(loop [n n xs coll]
|
||||
(if (and (pos? n) (seq xs))
|
||||
(recur (dec n) (rest xs))
|
||||
xs)))
|
||||
(if (pos? n)
|
||||
(or (loop [n n xs coll]
|
||||
(let [s (and (pos? n) (seq xs))]
|
||||
(if s (recur (dec n) (rest s)) (seq xs))))
|
||||
(list))
|
||||
coll))
|
||||
|
||||
(defn abs [x] (if (neg? x) (- 0 x) x))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue