Skip to content

Commit e621403

Browse files
Merge pull request #509 from angusiguess/master
Add sequence to stdlib
2 parents 828ae0b + c94144b commit e621403

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

pixie/stdlib.pxi

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ If further arguments are passed, invokes the method named by symbol, passing the
903903
(if (next coll)
904904
(recur (next coll))
905905
(first coll))
906-
906+
907907
(satisfies? ISeqable coll)
908908
(recur (seq coll))))
909909

@@ -1907,7 +1907,7 @@ not enough elements were present."
19071907

19081908
ISeqable
19091909
(-seq [self]
1910-
(reduce conj self)))
1910+
(sequence xform coll)))
19111911

19121912
(defn eduction
19131913
"Returns a reducible/iterable application of the transducers
@@ -2106,7 +2106,7 @@ For more information, see http://clojure.org/special_forms#binding-forms"}
21062106
val
21072107
not-found)))
21082108
ISeq
2109-
(-first [this]
2109+
(-first [this]
21102110
(when (not= start stop)
21112111
start))
21122112
(-next [this]
@@ -2188,6 +2188,20 @@ For more information, see http://clojure.org/special_forms#binding-forms"}
21882188
([pred coll]
21892189
(filter (complement pred) coll)))
21902190

2191+
(defn sequence
2192+
"Returns a lazy sequence of `data`, optionally transforming it using `xform`"
2193+
([coll]
2194+
(if (seq? coll) coll
2195+
(or (seq coll) ())))
2196+
([xform coll]
2197+
(let [step (defn step [xform acc xs]
2198+
(if-let [s (seq xs)]
2199+
(let [next-acc ((xform conj) acc (first s))]
2200+
(if (= acc next-acc) (step xform next-acc (next s))
2201+
(concat (drop (count acc) next-acc) (step xform next-acc (next s)))))
2202+
nil))]
2203+
(lazy-seq (step xform [] coll)))))
2204+
21912205
(defn distinct
21922206
{:doc "Returns the distinct elements in the collection."
21932207
:signatures [[] [coll]]
@@ -3080,7 +3094,7 @@ ex: (vary-meta x assoc :foo 42)"
30803094
(deftype Iterate [f x]
30813095
IReduce
30823096
(-reduce [self rf init]
3083-
(loop [next (f x)
3097+
(loop [next (f x)
30843098
acc (rf init x)]
30853099
(if (reduced? acc)
30863100
@acc

tests/pixie/tests/test-stdlib.pxi

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@
633633
(seq)))
634634
;; expanding transducer with nils
635635
(t/assert= '(1 2 3 nil 4 5 6 nil)
636-
(eduction cat [[1 2 3 nil] [4 5 6 nil]])))
636+
(seq (eduction cat [[1 2 3 nil] [4 5 6 nil]]))))
637637

638638
(t/deftest test-trace
639639
(try
@@ -805,3 +805,23 @@
805805
(t/assert= (reduce (fn [a v] (reduced "foo")) 0 (iterate inc 1)) "foo")
806806
(t/assert= (reduce (fn [a v] (if (< a 10) (+ a v) (reduced a))) 0 (iterate (partial + 2) 1)) 16))
807807

808+
(t/deftest test-sequence-empty-sequences
809+
(t/assert= '() (take 1 (sequence (map inc) '())))
810+
(t/assert= '() (take 1 (sequence (map inc) [])))
811+
(t/assert= '() (take 1 (sequence (map inc) #{})))
812+
(t/assert= '() (take 1 (sequence (map inc) {}))))
813+
814+
(t/deftest test-sequence-non-empty-sequences
815+
(t/assert= '(1 3) (take 2 (sequence (comp
816+
(filter even?)
817+
(map inc)) (range 3))))
818+
(t/assert= '(1) (take 1 (sequence (distinct) (repeat 4 1)))))
819+
820+
(t/deftest test-sequence-early-terminating-sequences
821+
(t/assert= '() (take 5 (sequence (filter (fn [x] false)) (repeat 8 8))))
822+
(t/assert= '(1 2) (take 3 (sequence (map identity) [1 2])))
823+
(t/assert= #{[:a 1] [:b 2]} (into #{} (take 3 (sequence (filter (fn [[k v]]
824+
(keyword? k)) {:a 1
825+
:b 2
826+
"c" 3
827+
"d" 4}))))))

0 commit comments

Comments
 (0)