Skip to content

Commit 0fead05

Browse files
authored
optimize seq-consuming library functions (#1198)
Optimize seq-consuming library functions to coerce their inputs into seqs before operating on them. Fixes #1234. --------- Co-authored-by: ikappaki <[email protected]>
1 parent 48fd08f commit 0fead05

File tree

2 files changed

+44
-35
lines changed

2 files changed

+44
-35
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
### Changed
1515
* Removed implicit support for single-use iterables in sequences, and introduced `iterator-seq` to expliciltly handle them (#1192)
1616
* `basilisp.core/str` now delegates to the builtin Python `str` in all cases except for customizing the string output for builtin Python types (#1237)
17+
* Optimised mainstream seq-consuming functions by coercing their inputs into `seq` upfront (#1234)
1718

1819
### Fixed
1920
* Fix a bug where protocols with methods with leading hyphens in the could not be defined (#1230)

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

0 commit comments

Comments
 (0)