Skip to content

Commit c8b0559

Browse files
committed
[wip] support generators in seq processing fns
1 parent 48fd08f commit c8b0559

File tree

2 files changed

+130
-36
lines changed

2 files changed

+130
-36
lines changed

src/basilisp/core.lpy

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2198,7 +2198,7 @@
21982198
[coll]
21992199
(let [do-reverse (fn do-reverse
22002200
[in out]
2201-
(if (seq in)
2201+
(if-let [in (seq in)]
22022202
(recur (rest in) (cons (first in) out))
22032203
out))]
22042204
(do-reverse coll '())))
@@ -2680,10 +2680,11 @@
26802680
(defn every?
26812681
"Return ``true`` if every element in ``coll`` satisfies ``pred``\\."
26822682
[pred coll]
2683-
(cond
2684-
(nil? (seq coll)) true
2685-
(pred (first coll)) (recur pred (rest coll))
2686-
:else false))
2683+
(let [coll (seq coll)]
2684+
(cond
2685+
(nil? coll) true
2686+
(pred (first coll)) (recur pred (rest coll))
2687+
:else false)))
26872688

26882689
(defn every-pred
26892690
"Return a predicate composed of all of the input predicates, which returns ``true``
@@ -2712,7 +2713,7 @@
27122713
(defn some
27132714
"Return ``true`` if at least one element in ``coll`` satisfies ``pred``\\."
27142715
[pred coll]
2715-
(when (seq coll)
2716+
(when-let [coll (seq coll)]
27162717
(or (pred (first coll))
27172718
(recur pred (rest coll)))))
27182719

@@ -2757,13 +2758,15 @@
27572758
(rf result (apply f input inputs))))))
27582759
([f coll]
27592760
(lazy-seq
2760-
(when (seq coll)
2761+
(when-let [coll (seq coll)]
27612762
(cons (f (first coll)) (map f (rest coll))))))
27622763
([f coll & colls]
27632764
(lazy-seq
2764-
(when (and (seq coll) (every? seq colls))
2765-
(cons (apply f (first coll) (map first colls))
2766-
(apply map f (rest coll) (map rest colls)))))))
2765+
(when-let [coll (seq coll)]
2766+
(let [colls (map seq colls)]
2767+
(when (every? some? colls)
2768+
(cons (apply f (first coll) (map first colls))
2769+
(apply map f (rest coll) (map rest colls)))))))))
27672770

27682771
(def ^{:doc "Return a vector of ``(f elem)`` for elements in ``coll``\\. More than one
27692772
collection may be supplied. If more than one collection is supplied, the
@@ -2818,7 +2821,7 @@
28182821
result)))))
28192822
([pred coll]
28202823
(lazy-seq
2821-
(when (seq coll)
2824+
(when-let [coll (seq coll)]
28222825
(if (pred (first coll))
28232826
(cons (first coll) (filter pred (rest coll)))
28242827
(filter pred (rest coll)))))))
@@ -2853,7 +2856,7 @@
28532856
(rf result v)))))))
28542857
([f coll]
28552858
(lazy-seq
2856-
(when (seq coll)
2859+
(when-let [coll (seq coll)]
28572860
(let [elem (f (first coll))]
28582861
(if (nil? elem)
28592862
(keep f (rest coll))
@@ -2879,7 +2882,7 @@
28792882
(let [keep-idx (fn keep-idx
28802883
[rng coll]
28812884
(lazy-seq
2882-
(when (seq coll)
2885+
(when-let [coll (seq coll)]
28832886
(let [elem (f (first rng) (first coll))]
28842887
(if (nil? elem)
28852888
(keep-idx (rest rng) (rest coll))
@@ -2901,7 +2904,7 @@
29012904
([n coll]
29022905
(lazy-seq
29032906
(when (> n 0)
2904-
(when (seq coll)
2907+
(when-let [coll (seq coll)]
29052908
(cons (first coll) (take (dec n) (rest coll))))))))
29062909

29072910
(defn take-while
@@ -2919,7 +2922,7 @@
29192922
(ensure-reduced result))))))
29202923
([pred coll]
29212924
(lazy-seq
2922-
(when (seq coll)
2925+
(when-let [coll (seq coll)]
29232926
(when (pred (first coll))
29242927
(cons (first coll) (take-while pred (rest coll))))))))
29252928

@@ -2939,7 +2942,7 @@
29392942
(rf result input)))))))
29402943
([n coll]
29412944
(lazy-seq
2942-
(when (seq coll)
2945+
(when-let [coll (seq coll)]
29432946
(if (> n 0)
29442947
(drop (dec n) (rest coll))
29452948
(seq coll))))))
@@ -2961,7 +2964,7 @@
29612964
:else result))))))
29622965
([pred coll]
29632966
(lazy-seq
2964-
(when (seq coll)
2967+
(when-let [coll (seq coll)]
29652968
(if (pred (first coll))
29662969
(drop-while pred (rest coll))
29672970
(seq coll))))))
@@ -3031,7 +3034,7 @@
30313034
(rf (rf result sep) input)))))))
30323035
([sep coll]
30333036
(lazy-seq
3034-
(when (seq coll)
3037+
(when-let [coll (seq coll)]
30353038
(if (seq (rest coll))
30363039
(cons (first coll)
30373040
(cons sep (interpose sep (rest coll))))
@@ -3050,14 +3053,17 @@
30503053
(when (seq colls)
30513054
(cons (ffirst colls) (apply coll-firsts (rest colls))))))]
30523055
(lazy-seq
3053-
(when (and (seq coll) (every? seq colls))
3054-
(concat (apply coll-firsts coll colls)
3055-
(apply interleave (rest coll) (map rest colls))))))))
3056+
(when-let [coll (seq coll)]
3057+
(let [colls (map seq colls)]
3058+
(when (every? some? colls)
3059+
(concat (apply coll-firsts coll colls)
3060+
(apply interleave (rest coll) (map rest colls))))))))))
30563061

30573062
(defn cycle
30583063
"Cycle the items in ``coll`` infinitely."
30593064
[coll]
3060-
(let [coll-cycle (fn coll-cycle
3065+
(let [coll (seq coll)
3066+
coll-cycle (fn coll-cycle
30613067
[curr]
30623068
(lazy-seq
30633069
(if (seq curr)
@@ -3103,7 +3109,7 @@
31033109
result)))))))
31043110
([n coll]
31053111
(lazy-seq
3106-
(when (seq coll)
3112+
(when-let [coll (seq coll)]
31073113
(if (<= n 0)
31083114
(repeat (first coll))
31093115
(cons (first coll)
@@ -3120,13 +3126,13 @@
31203126
(partition n n coll))
31213127
([n step coll]
31223128
(lazy-seq
3123-
(when (seq coll)
3129+
(when-let [coll (seq coll)]
31243130
(let [s (take n coll)]
31253131
(when (= n (count s))
31263132
(cons s (partition n step (drop step coll))))))))
31273133
([n step pad coll]
31283134
(lazy-seq
3129-
(when (seq coll)
3135+
(when-let [coll (seq coll)]
31303136
(let [s (take n coll)
31313137
ns (count s)
31323138
s (if (< ns n)
@@ -3163,7 +3169,7 @@
31633169
(partition-all n n coll))
31643170
([n step coll]
31653171
(lazy-seq
3166-
(when (seq coll)
3172+
(when-let [coll (seq coll)]
31673173
(cons (take n coll) (partition-all n step (drop step coll)))))))
31683174

31693175
(defn partition-by
@@ -3203,7 +3209,7 @@
32033209
(rf result elem)))))))))
32043210
([f coll]
32053211
(lazy-seq
3206-
(when (seq coll)
3212+
(when-let [coll (seq coll)]
32073213
(let [elem (first coll)
32083214
felem (f elem)
32093215
run (cons elem (take-while #(= felem (f %)) (next coll)))]
@@ -3228,7 +3234,7 @@
32283234
(let [coll-distinct (fn coll-distinct
32293235
[coll found]
32303236
(lazy-seq
3231-
(when (seq coll)
3237+
(when-let [coll (seq coll)]
32323238
(let [e (first coll)]
32333239
(if-not (contains? found e)
32343240
(cons e (coll-distinct (rest coll) (conj found e)))
@@ -3262,8 +3268,9 @@
32623268
(cons e (coll-dedupe (rest coll) e))
32633269
(coll-dedupe (rest coll) prev))))))]
32643270
(lazy-seq
3265-
(when-let [e (first coll)]
3266-
(cons e (coll-dedupe (rest coll) e)))))))
3271+
(let [coll (seq coll)]
3272+
(when-let [e (first coll)]
3273+
(cons e (coll-dedupe (rest coll) e))))))))
32673274

32683275
(defn flatten
32693276
"Flatten any combination of nested sequences (such as lists or vectors) into a single
@@ -3281,11 +3288,12 @@
32813288
(defn take-last
32823289
"Return the last ``n`` items in ``coll`` in linear time."
32833290
[n coll]
3284-
(loop [c (seq coll)
3285-
rem (seq (drop n coll))]
3286-
(if rem
3287-
(recur (next c) (next rem))
3288-
c)))
3291+
(let [coll (seq coll)]
3292+
(loop [c coll
3293+
rem (seq (drop n coll))]
3294+
(if rem
3295+
(recur (next c) (next rem))
3296+
c))))
32893297

32903298
(defn min-key
32913299
"Return the arg for which ``(k arg)`` is the smallest number. If multiple values

tests/basilisp/test_core_fns.lpy

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2497,6 +2497,92 @@
24972497
cat
24982498
(iteration range-chunk :somef (partial some #(< % 7)) :kf (comp inc last) :initk 0))))))
24992499

2500+
(def test-generator-vals [0 1 2 "three" nil 5])
2501+
2502+
(defn test-generator []
2503+
(dotimes [i (count test-generator-vals)]
2504+
(yield (nth test-generator-vals i))))
2505+
2506+
(deftest python-iterators-seq-fns-test
2507+
;; The plan here is to consume with each function the test generator
2508+
;; in its entirety, and check for missing values.
2509+
2510+
(testing "every?"
2511+
(let [nums* (atom [])]
2512+
(is (every? #(do (swap! nums* conj %)
2513+
(or (number? %) (string? %) (nil? %)))
2514+
(test-generator)))
2515+
(is (= test-generator-vals @nums*))))
2516+
2517+
(testing "some"
2518+
(let [nums* (atom [])]
2519+
(is (some #(do (swap! nums* conj %)
2520+
(= % 5))
2521+
(test-generator)))
2522+
(is (= test-generator-vals @nums*))))
2523+
2524+
(testing "map"
2525+
(is (= test-generator-vals (map identity (test-generator))))
2526+
(is (= ["00" "11" "22" "threethree" "" "55"] (map str (test-generator) (test-generator)))))
2527+
2528+
(testing "filter"
2529+
(is (= [0 1 2 5] (filter #(and (number? %) (> % -1)) (test-generator)))))
2530+
2531+
(testing "keep"
2532+
(is (= [0 1 2 "three" 5] (keep identity (test-generator)))))
2533+
2534+
(testing "keep-indexed"
2535+
(is (= [[0 0] [1 1] [2 2] [3 "three"] [4 nil] [5 5]] (keep-indexed vector (test-generator)))))
2536+
2537+
(testing "take"
2538+
(is (= test-generator-vals (take 6 (test-generator)))))
2539+
2540+
(testing "take-while"
2541+
(is (= test-generator-vals (take-while #(not= % 7) (test-generator)))))
2542+
2543+
(testing "take-while"
2544+
(is (= test-generator-vals (drop 0 (test-generator)))))
2545+
2546+
(testing "take-while"
2547+
(is (= [1 2 "three" nil 5] (drop-while #(not= % 1) (test-generator)))))
2548+
2549+
(testing "interpose"
2550+
(is (= [0 "-" 1 "-" 2 "-" "three" "-" nil "-" 5] (interpose "-" (test-generator)))))
2551+
2552+
(testing "interleave"
2553+
(is (= [0 0 1 1 2 2 "three" "three" nil nil 5 5] (interleave (test-generator) (test-generator)))))
2554+
2555+
(testing "cycle"
2556+
(is (= [0 1 2 "three" nil 5 0 1 2 "three"] (take 10 (cycle (test-generator))))))
2557+
2558+
(testing "take-nth"
2559+
(is (= [0 2 nil] (take-nth 2 (test-generator)))))
2560+
2561+
(testing "partition"
2562+
(is (= [[0 1] [2 "three"] [nil 5]] (partition 2 (test-generator))))
2563+
(is (= [[0 1] [1 2] [2 "three"] ["three" nil] [nil 5]] (partition 2 1 (test-generator))))
2564+
(is (= [[0 1 2 "three"] [nil 5 :pad :pad]] (partition 4 4 (repeat :pad) (test-generator)))))
2565+
2566+
(testing "partition-all"
2567+
(is (= [[0 1 2 "three"] [nil 5]] (partition-all 4 (test-generator))))
2568+
(is (= [[0 1 2 "three"] [nil 5]] (partition-all 4 4 (test-generator)))))
2569+
2570+
(testing "distinct"
2571+
(is (= test-generator-vals (dedupe (test-generator)))))
2572+
2573+
;; TODO
2574+
;; (testing "flatten"
2575+
;; (is (= nil (flatten [[:a :b :c] (test-generator)]))))
2576+
2577+
2578+
(testing "take-last"
2579+
(is (= [2 "three" nil 5] (take-last 4 (test-generator)))))
2580+
2581+
(testing "sort-by"
2582+
(is (= [5 nil "three" 2 1 0] (reverse (test-generator)))))
2583+
2584+
)
2585+
25002586
;;;;;;;;;;
25012587
;; Taps ;;
25022588
;;;;;;;;;;
@@ -2514,7 +2600,7 @@
25142600
a2-fn #(swap! a2-atom conj [:a2 %])
25152601
b-fn #(swap! b-atom conj %)]
25162602
(add-tap def-fn)
2517-
(remove-tap b-fn) ;; not an error
2603+
(remove-tap b-fn) ;; not an error
25182604
(tap> "this is a test")
25192605

25202606
;; Wait for the tap thread to drain

0 commit comments

Comments
 (0)