From f0e111563b340fa5e9950b409d67b963c1fc0cce Mon Sep 17 00:00:00 2001 From: Yogthos Date: Sun, 7 Jun 2026 00:14:40 -0400 Subject: [PATCH] core: move dedupe + seq-to-map-for-destructuring to overlay (+ tests) Eighth pure-fn batch (jolt-1j0 phase 2), 2 leaf fns. dedupe is eager consecutive dedup (no transducer arity, as before); seq-to-map-for-destructuring is the internal &{:keys} helper. Largely exhausts the easy pure-eager tier. conformance 228/228 x3, full suite green (incl. destructuring). --- jolt-core/clojure/core/20-coll.clj | 21 +++++++++++++++++++++ src/jolt/core.janet | 18 ------------------ test/spec/sequences-spec.janet | 5 ++++- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/jolt-core/clojure/core/20-coll.clj b/jolt-core/clojure/core/20-coll.clj index 8e6e21f..03bd0eb 100644 --- a/jolt-core/clojure/core/20-coll.clj +++ b/jolt-core/clojure/core/20-coll.clj @@ -192,3 +192,24 @@ ;; No ratio type on Jolt, so rationalize is identity. (defn rationalize [x] x) + +;; Eager dedupe of consecutive equal elements (Jolt has no transducer arity yet). +(defn dedupe [coll] + (let [c (vec coll)] + (if (empty? c) + [] + (loop [prev (first c) xs (rest c) out [(first c)]] + (if (seq xs) + (let [x (first xs)] + (recur x (rest xs) (if (= x prev) out (conj out x)))) + out))))) + +;; Internal helper for {:keys [...]} destructuring over a seq of k/v pairs: +;; builds a map from consecutive pairs, dropping a trailing unpaired element. +(defn seq-to-map-for-destructuring [s] + (if (sequential? s) + (loop [m {} xs (seq s)] + (if (and xs (next xs)) + (recur (assoc m (first xs) (second xs)) (next (next xs))) + m)) + s)) diff --git a/src/jolt/core.janet b/src/jolt/core.janet index daec67d..d1e681a 100644 --- a/src/jolt/core.janet +++ b/src/jolt/core.janet @@ -1254,14 +1254,6 @@ (+= i n)) result)) -(defn core-dedupe [coll] - (let [c (realize-for-iteration coll) result @[]] - (var prev :jolt/none) - (each x c - (when (or (= prev :jolt/none) (not (deep= x prev))) - (array/push result x)) - (set prev x)) - (tuple/slice (tuple ;result)))) (defn core-keep-indexed [f coll] (let [c (realize-for-iteration coll) result @[]] @@ -3210,14 +3202,6 @@ (var parts @[]) (each x xs (array/push parts (str-render-one x))) (string/join parts " ")) (defn core-memfn [& args] (error "memfn: JVM method handles are not supported in Jolt")) -(defn core-seq-to-map-for-destructuring [s] - # used by {:keys [...]} destructuring over a seq of k/v pairs - (if (core-sequential? s) - (let [items (realize-for-iteration s) m @{}] - (var i 0) - (while (< (+ i 1) (length items)) (put m (in items i) (in items (+ i 1))) (+= i 2)) - (table/to-struct m)) - s)) (defn core-eduction [& args] # (eduction xform* coll): apply the composed transducers eagerly to coll (let [n (length args) @@ -3540,7 +3524,6 @@ "contains?" core-contains? "count" core-count "partition-all" core-partition-all - "dedupe" core-dedupe "keep-indexed" core-keep-indexed "map-indexed" core-map-indexed "cycle" core-cycle @@ -3805,7 +3788,6 @@ "==" core-numeric= "print-str" core-print-str "memfn" core-memfn - "seq-to-map-for-destructuring" core-seq-to-map-for-destructuring "eduction" core-eduction "->Eduction" core->Eduction "proxy-super" core-proxy-super diff --git a/test/spec/sequences-spec.janet b/test/spec/sequences-spec.janet index 1fee5b0..58675f0 100644 --- a/test/spec/sequences-spec.janet +++ b/test/spec/sequences-spec.janet @@ -244,4 +244,7 @@ ["flatten scalar -> empty" "[]" "(flatten 5)"] ["interleave" "[1 :a 2 :b]" "(interleave [1 2 3] [:a :b])"] ["interleave empty" "[]" "(interleave)"] - ["rationalize identity" "5" "(rationalize 5)"]) + ["rationalize identity" "5" "(rationalize 5)"] + ["dedupe consecutive" "[1 2 3 1]" "(dedupe [1 1 2 2 3 1 1])"] + ["dedupe empty" "[]" "(dedupe [])"] + ["dedupe no dups" "[1 2 3]" "(dedupe [1 2 3])"])