Skip to content

Commit ecc545f

Browse files
authored
Fix the definition of reduce (#567)
* Fix the definition of `reduce` * Changelog
1 parent 296ab78 commit ecc545f

File tree

4 files changed

+87
-102
lines changed

4 files changed

+87
-102
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3434
* Fixed multiple bugs relating to symbol resolution of `import`ed symbols in various contexts (#544)
3535
* Fixed a bug where the `=` function did not respect the equality partition for various builtin collection types (#556)
3636
* Fixed a bug where collection types could evaluate as boolean `false` (#566)
37+
* Fixed a bug where `reduce` required a 1-arity function for the variant with an initial value, rather than returning that initial value (#567)
3738

3839
## [v0.1.dev13] - 2020-03-16
3940
### Added

src/basilisp/core.lpy

Lines changed: 45 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,22 +2087,22 @@
20872087
(fn [& ^:no-warn-when-unused args] x))
20882088

20892089
(defn reduce
2090-
"Reduce coll by f.
2090+
"Reduce `coll` by `f`.
20912091

2092-
If val is not supplied and coll has no elements, f will be called
2092+
If `val` is not supplied and `coll` has no elements, `f` will be called
20932093
with no arguments and the result will be returned.
20942094

2095-
If val is not supplied and coll has one element, the result of
2096-
(f (first val)) is returned.
2095+
If `val` is not supplied and `coll` has one element, the result of
2096+
`(f (first val))` is returned.
20972097

2098-
If val is not supplied and coll has elements, repeatedly reduce coll
2099-
by calling f on successive elements in coll.
2098+
If `val` is not supplied and `coll` has elements, repeatedly reduce `coll`
2099+
by calling `f` on successive elements in `coll`.
21002100

2101-
If val is supplied and coll has no elements, the result of (f val)
2102-
is returned.
2101+
If `val` is supplied and `coll` has no elements, return `val` and `f` will
2102+
not be called.
21032103

2104-
If val is supplied and coll has elements, repeatedly reduce coll
2105-
by calling f on successive elements in coll, starting with val."
2104+
If `val` is supplied and `coll` has elements, repeatedly reduce coll
2105+
by calling `f` on successive elements in `coll`, starting with `val`."
21062106
([f coll]
21072107
(if (seq coll)
21082108
(if (seq (rest coll))
@@ -2116,7 +2116,7 @@
21162116
out))]
21172117
(if (seq coll)
21182118
(reduce-coll val coll)
2119-
(f val)))))
2119+
val))))
21202120

21212121
(defn reduce-kv
21222122
"Reduce an associative coll by f. f must be a function of 3
@@ -2407,29 +2407,25 @@
24072407
"Return a map whose keys are the elements of coll and whose values are
24082408
the counts for the number of times the key appears in coll."
24092409
[coll]
2410-
(if-not (seq coll)
2411-
{}
2412-
(reduce (fn [m v]
2413-
(if (contains? m v)
2414-
(update m v inc)
2415-
(assoc m v 1)))
2416-
{}
2417-
coll)))
2410+
(reduce (fn [m v]
2411+
(if (contains? m v)
2412+
(update m v inc)
2413+
(assoc m v 1)))
2414+
{}
2415+
coll))
24182416

24192417
(defn group-by
24202418
"Return a map whose keys are the result of calling f on each element
24212419
in coll and whose values are vectors of the values which produced the
24222420
corresponding key, in the order they were added."
24232421
[f coll]
2424-
(if-not (seq coll)
2425-
{}
2426-
(reduce (fn [m v]
2427-
(let [group (f v)]
2428-
(if (contains? m group)
2429-
(update m group conj v)
2430-
(assoc m group [v]))))
2431-
{}
2432-
coll)))
2422+
(reduce (fn [m v]
2423+
(let [group (f v)]
2424+
(if (contains? m group)
2425+
(update m group conj v)
2426+
(assoc m group [v]))))
2427+
{}
2428+
coll))
24332429

24342430
(defn interpose
24352431
"Return a lazy sequence of elements of coll separated by sep. If
@@ -3686,15 +3682,12 @@
36863682

36873683
Public vars are Vars which are declared without :private metadata."
36883684
[ns]
3689-
(let [interns (ns-interns (the-ns ns))]
3690-
(if-not (seq interns)
3691-
{}
3692-
(reduce (fn [m entry]
3693-
(if (:private (meta (val entry)))
3694-
m
3695-
(assoc m (key entry) (val entry))))
3696-
{}
3697-
interns))))
3685+
(reduce (fn [m entry]
3686+
(if (:private (meta (val entry)))
3687+
m
3688+
(assoc m (key entry) (val entry))))
3689+
{}
3690+
(ns-interns (the-ns ns))))
36983691

36993692
(defn ns-refers
37003693
"Return a map of symbols to Vars which are referred in the current
@@ -3931,16 +3924,15 @@
39313924
(let [doc (when (string? (first opts))
39323925
(first opts))
39333926
opts (if doc (rest opts) opts)
3934-
opts (when (seq opts)
3935-
(reduce (fn [m opt]
3936-
(let [opt-name (first opt)
3937-
options (rest opt)]
3938-
(when-not (keyword? opt-name)
3939-
(throw (ex-info "Namespace option must be a keyword"
3940-
{:option opt-name})))
3941-
(assoc m opt-name (vec options))))
3942-
{}
3943-
opts))
3927+
opts (reduce (fn [m opt]
3928+
(let [opt-name (first opt)
3929+
options (rest opt)]
3930+
(when-not (keyword? opt-name)
3931+
(throw (ex-info "Namespace option must be a keyword"
3932+
{:option opt-name})))
3933+
(assoc m opt-name (vec options))))
3934+
{}
3935+
opts)
39443936

39453937
refer-filters (when-let [filters (or (:refer-basilisp opts)
39463938
(:refer-clojure opts))]
@@ -4095,14 +4087,12 @@
40954087
(defn select-keys
40964088
"Return a map with only the keys of m which are in ks."
40974089
[m ks]
4098-
(if-not (seq ks)
4099-
{}
4100-
(reduce (fn [new-map k]
4101-
(if (contains? m k)
4102-
(assoc new-map k (get m k))
4103-
new-map))
4104-
{}
4105-
ks)))
4090+
(reduce (fn [new-map k]
4091+
(if (contains? m k)
4092+
(assoc new-map k (get m k))
4093+
new-map))
4094+
{}
4095+
ks))
41064096

41074097
;;;;;;;;;;;;;;;;;;;;;;;;;;;
41084098
;; Destructuring Support ;;

src/basilisp/set.lpy

Lines changed: 37 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,13 @@
1919
"Given a set of maps, return a mapping of unique selections of keys
2020
from ks to the set of values which have those mappings."
2121
[rel ks]
22-
(if-not (seq rel)
23-
{}
24-
(reduce (fn [m v]
25-
(let [index-val (select-keys v ks)]
26-
(if (contains? m index-val)
27-
(update m index-val conj v)
28-
(assoc m index-val #{v}))))
29-
{}
30-
rel)))
22+
(reduce (fn [m v]
23+
(let [index-val (select-keys v ks)]
24+
(if (contains? m index-val)
25+
(update m index-val conj v)
26+
(assoc m index-val #{v}))))
27+
{}
28+
rel))
3129

3230
(defn intersection
3331
"Return a new set with only elements in s1 that are in all
@@ -42,12 +40,10 @@
4240
Duplicate values used as keys will overwrite each other as
4341
iteration order is non-deterministic."
4442
[m]
45-
(if-not (seq m)
46-
m
47-
(reduce (fn [m entry]
48-
(assoc m (val entry) (key entry)))
49-
{}
50-
m)))
43+
(reduce (fn [m entry]
44+
(assoc m (val entry) (key entry)))
45+
{}
46+
m))
5147

5248
(defn project
5349
"Given a set of maps, return a set of those maps with only the keys in ks."
@@ -58,18 +54,16 @@
5854
"Return m with any keys appearing in kmap replaced with the value
5955
in kmap."
6056
[m kmap]
61-
(if-not (seq m)
62-
m
63-
(reduce (fn [m entry]
64-
(let [orig-k (key entry)
65-
new-k (val entry)]
66-
(if (contains? m orig-k)
67-
(let [v (get m orig-k)
68-
clean-map (dissoc m orig-k)]
69-
(assoc clean-map new-k v))
70-
m)))
71-
m
72-
kmap)))
57+
(reduce (fn [m entry]
58+
(let [orig-k (key entry)
59+
new-k (val entry)]
60+
(if (contains? m orig-k)
61+
(let [v (get m orig-k)
62+
clean-map (dissoc m orig-k)]
63+
(assoc clean-map new-k v))
64+
m)))
65+
m
66+
kmap))
7367

7468
(defn rename
7569
"Given a set of maps, return a set whose maps have had any keys in kmap
@@ -127,28 +121,24 @@
127121

128122
lindex (index lrel shared)
129123
rindex (index rrel shared)]
130-
(if-not (seq lindex)
131-
#{}
132-
(reduce (fn [s [k l-indexed]]
133-
(if (contains? rindex k)
134-
(apply conj s (product merge l-indexed (get rindex k)))
135-
s))
136-
#{}
137-
lindex))))
124+
(reduce (fn [s [k l-indexed]]
125+
(if (contains? rindex k)
126+
(apply conj s (product merge l-indexed (get rindex k)))
127+
s))
128+
#{}
129+
lindex)))
138130
([lrel rrel keymap]
139131
(let [[f s ks] (if (<= (count lrel) (count rrel))
140132
[lrel rrel (map-invert keymap)]
141133
[rrel lrel keymap])
142134
idx (index f (vals ks))]
143-
(if-not (seq s)
144-
#{}
145-
(reduce (fn [ret x]
146-
(let [match (idx (rename-keys (select-keys x (keys ks)) ks))]
147-
(if match
148-
(reduce (fn [s v]
149-
(conj s (merge v x)))
150-
ret
151-
match)
152-
ret)))
153-
#{}
154-
s)))))
135+
(reduce (fn [ret x]
136+
(let [match (idx (rename-keys (select-keys x (keys ks)) ks))]
137+
(if match
138+
(reduce (fn [s v]
139+
(conj s (merge v x)))
140+
ret
141+
match)
142+
ret)))
143+
#{}
144+
s))))

tests/basilisp/test_core_fns.lpy

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,10 +531,14 @@
531531
:methods '[(method [thing1 thing2])
532532
(method [& args])]))
533533

534+
(is (not (nil? (gen-interface :name "TestInterface"))))
535+
534536
(are [arity-names methods] (let [interface (gen-interface :name "TestInterface"
535537
:methods methods)]
536538
(set/superset? (set (python/dir interface))
537539
(set arity-names)))
540+
[] []
541+
538542
["method"]
539543
'[(method [arg])]
540544

0 commit comments

Comments
 (0)