core: move comparator/reductions/tree-seq to overlay (+ spec tests)
Sixth pure-fn batch (jolt-1j0 phase 2), 3 leaf fns, now with regression tests per the per-batch workflow. reductions is the canonical form, so (reductions f []) calls (f) -> [0] instead of the prior []; tree-seq is eager pre-order DFS. conformance 228/228 x3, clojure-test-suite 3929, full suite green, bench A/B flat.
This commit is contained in:
parent
c35cf7bdbc
commit
921b395dfd
3 changed files with 33 additions and 29 deletions
|
|
@ -143,3 +143,28 @@
|
||||||
(defn undefined? [x] false)
|
(defn undefined? [x] false)
|
||||||
|
|
||||||
(defn keyword-identical? [a b] (= a b))
|
(defn keyword-identical? [a b] (= a b))
|
||||||
|
|
||||||
|
(defn comparator [pred]
|
||||||
|
(fn [a b] (cond (pred a b) -1 (pred b a) 1 :else 0)))
|
||||||
|
|
||||||
|
;; Eager (Jolt has no laziness yet): a vector of the running accumulators.
|
||||||
|
(defn reductions
|
||||||
|
([f coll]
|
||||||
|
(let [s (seq coll)]
|
||||||
|
(if s
|
||||||
|
(reductions f (first s) (rest s))
|
||||||
|
(list (f)))))
|
||||||
|
([f init coll]
|
||||||
|
(loop [acc init xs (seq coll) out [init]]
|
||||||
|
(if xs
|
||||||
|
(let [a (f acc (first xs))] (recur a (next xs) (conj out a)))
|
||||||
|
out))))
|
||||||
|
|
||||||
|
;; Eager pre-order DFS (Clojure's is lazy; same order, fully realized here).
|
||||||
|
(defn tree-seq [branch? children root]
|
||||||
|
(let [walk (fn walk [acc node]
|
||||||
|
(let [acc (conj acc node)]
|
||||||
|
(if (branch? node)
|
||||||
|
(reduce walk acc (children node))
|
||||||
|
acc)))]
|
||||||
|
(walk [] root)))
|
||||||
|
|
|
||||||
|
|
@ -1254,21 +1254,6 @@
|
||||||
(+= i n))
|
(+= i n))
|
||||||
result))
|
result))
|
||||||
|
|
||||||
(defn core-reductions
|
|
||||||
"(reductions f coll) or (reductions f init coll) -> seq of intermediate accs."
|
|
||||||
[f init-or-coll &opt maybe-coll]
|
|
||||||
(let [has-init (not (nil? maybe-coll))
|
|
||||||
coll (realize-for-iteration (if has-init maybe-coll init-or-coll))
|
|
||||||
result @[]]
|
|
||||||
(if has-init
|
|
||||||
(do (var acc init-or-coll) (array/push result acc)
|
|
||||||
(each x coll (set acc (f acc x)) (array/push result acc)))
|
|
||||||
(when (> (length coll) 0)
|
|
||||||
(var acc (in coll 0)) (array/push result acc)
|
|
||||||
(var i 1)
|
|
||||||
(while (< i (length coll)) (set acc (f acc (in coll i))) (array/push result acc) (++ i))))
|
|
||||||
(tuple/slice (tuple ;result))))
|
|
||||||
|
|
||||||
(defn core-dedupe [coll]
|
(defn core-dedupe [coll]
|
||||||
(let [c (realize-for-iteration coll) result @[]]
|
(let [c (realize-for-iteration coll) result @[]]
|
||||||
(var prev :jolt/none)
|
(var prev :jolt/none)
|
||||||
|
|
@ -3318,14 +3303,6 @@
|
||||||
(defn core-dorun [a & rest]
|
(defn core-dorun [a & rest]
|
||||||
(let [coll (if (= 0 (length rest)) a (in rest 0))]
|
(let [coll (if (= 0 (length rest)) a (in rest 0))]
|
||||||
(realize-for-iteration coll) nil))
|
(realize-for-iteration coll) nil))
|
||||||
(defn core-tree-seq [branch? children root]
|
|
||||||
(def out @[])
|
|
||||||
(defn walk [node]
|
|
||||||
(array/push out node)
|
|
||||||
(when (truthy? (branch? node))
|
|
||||||
(each c (realize-for-iteration (children node)) (walk c))))
|
|
||||||
(walk root)
|
|
||||||
(tuple ;out))
|
|
||||||
|
|
||||||
# Map entries (represented as 2-element vectors)
|
# Map entries (represented as 2-element vectors)
|
||||||
# key/val require a map entry (a 2-element vector/tuple in Jolt); Clojure throws
|
# key/val require a map entry (a 2-element vector/tuple in Jolt); Clojure throws
|
||||||
|
|
@ -3385,8 +3362,6 @@
|
||||||
(defn core-promise [] (core-atom nil))
|
(defn core-promise [] (core-atom nil))
|
||||||
(defn core-deliver [p v] (core-reset! p v) p)
|
(defn core-deliver [p v] (core-reset! p v) p)
|
||||||
|
|
||||||
(defn core-comparator [pred]
|
|
||||||
(fn [a b] (cond (truthy? (pred a b)) -1 (truthy? (pred b a)) 1 true 0)))
|
|
||||||
(defn core-tagged-literal [tag form] @{:jolt/type :jolt/tagged-literal :tag tag :form form})
|
(defn core-tagged-literal [tag form] @{:jolt/type :jolt/tagged-literal :tag tag :form form})
|
||||||
(defn core-ensure-reduced [x] (if (core-reduced? x) x (core-reduced x)))
|
(defn core-ensure-reduced [x] (if (core-reduced? x) x (core-reduced x)))
|
||||||
(defn core-halt-when [pred & rest]
|
(defn core-halt-when [pred & rest]
|
||||||
|
|
@ -3594,7 +3569,6 @@
|
||||||
"contains?" core-contains?
|
"contains?" core-contains?
|
||||||
"count" core-count
|
"count" core-count
|
||||||
"partition-all" core-partition-all
|
"partition-all" core-partition-all
|
||||||
"reductions" core-reductions
|
|
||||||
"dedupe" core-dedupe
|
"dedupe" core-dedupe
|
||||||
"keep-indexed" core-keep-indexed
|
"keep-indexed" core-keep-indexed
|
||||||
"map-indexed" core-map-indexed
|
"map-indexed" core-map-indexed
|
||||||
|
|
@ -3627,7 +3601,6 @@
|
||||||
"apply" core-apply
|
"apply" core-apply
|
||||||
"doall" core-doall
|
"doall" core-doall
|
||||||
"dorun" core-dorun
|
"dorun" core-dorun
|
||||||
"tree-seq" core-tree-seq
|
|
||||||
"key" core-key
|
"key" core-key
|
||||||
"val" core-val
|
"val" core-val
|
||||||
"map-entry?" core-map-entry?
|
"map-entry?" core-map-entry?
|
||||||
|
|
@ -3651,7 +3624,6 @@
|
||||||
"future-done?" core-future-done?
|
"future-done?" core-future-done?
|
||||||
"future-cancel" core-future-cancel
|
"future-cancel" core-future-cancel
|
||||||
"future-cancelled?" core-future-cancelled?
|
"future-cancelled?" core-future-cancelled?
|
||||||
"comparator" core-comparator
|
|
||||||
"tagged-literal" core-tagged-literal
|
"tagged-literal" core-tagged-literal
|
||||||
"ensure-reduced" core-ensure-reduced
|
"ensure-reduced" core-ensure-reduced
|
||||||
"unreduced" core-unreduced
|
"unreduced" core-unreduced
|
||||||
|
|
|
||||||
|
|
@ -227,4 +227,11 @@
|
||||||
["replicate" "[:x :x :x]" "(replicate 3 :x)"]
|
["replicate" "[:x :x :x]" "(replicate 3 :x)"]
|
||||||
["bounded-count" "3" "(bounded-count 3 [1 2 3 4 5])"]
|
["bounded-count" "3" "(bounded-count 3 [1 2 3 4 5])"]
|
||||||
["run! side effects" "6" "(let [a (atom 0)] (run! (fn [x] (swap! a + x)) [1 2 3]) @a)"]
|
["run! side effects" "6" "(let [a (atom 0)] (run! (fn [x] (swap! a + x)) [1 2 3]) @a)"]
|
||||||
["completing wraps rf" "3" "((completing +) 1 2)"])
|
["completing wraps rf" "3" "((completing +) 1 2)"]
|
||||||
|
["comparator <" "[1 2 3]" "(sort (comparator <) [3 1 2])"]
|
||||||
|
["comparator >" "[3 2 1]" "(sort (comparator >) [3 1 2])"]
|
||||||
|
["reductions" "[1 3 6 10]" "(reductions + [1 2 3 4])"]
|
||||||
|
["reductions with init" "[10 11 13 16]" "(reductions + 10 [1 2 3])"]
|
||||||
|
["reductions empty calls f" "[0]" "(reductions + [])"]
|
||||||
|
["reductions empty + init" "[5]" "(reductions + 5 [])"]
|
||||||
|
["tree-seq pre-order" "[[1 [2] 3] 1 [2] 2 3]" "(tree-seq sequential? seq [1 [2] 3])"])
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue