File tree Expand file tree Collapse file tree 3 files changed +46
-7
lines changed Expand file tree Collapse file tree 3 files changed +46
-7
lines changed Original file line number Diff line number Diff line change @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
10
10
11
11
### Fixed
12
12
* Fix a bug where symbols and keyword containing ` : ` characters in the name were rejected by the reader (#1105 )
13
+ * Fix a bug where records did not support reducing via ` reduce-kv ` (#1102 )
13
14
14
15
## [ v0.3.0]
15
16
### Added
Original file line number Diff line number Diff line change 6842
6842
in the body of a method should not include that parameter, as it will be supplied
6843
6843
automatically."
6844
6844
[type-name fields & method-impls]
6845
- (let [ctor-name (with-meta
6846
- (symbol (str "->" (name type-name)))
6847
- (meta type-name))
6848
- map-ctor (with-meta
6849
- (symbol (str "map->" (name type-name)))
6850
- (meta type-name))
6845
+ (let [ctor-name (with-meta
6846
+ (symbol (str "->" (name type-name)))
6847
+ (meta type-name))
6848
+ map-ctor (with-meta
6849
+ (symbol (str "map->" (name type-name)))
6850
+ (meta type-name))
6851
6851
6852
6852
record-fields (vec (concat fields
6853
6853
['^{:default nil} meta
6861
6861
'[basilisp.lang.interfaces/IPersistentMap
6862
6862
basilisp.lang.interfaces/IWithMeta
6863
6863
basilisp.lang.interfaces/IRecord
6864
+ basilisp.lang.interfaces/IReduceKV
6864
6865
python/object])
6865
6866
6866
6867
;; We can use these gensyms repeatedly and interpolate them in
7005
7006
(str "#" ~(name *ns*) "." qual-name))
7006
7007
print-meta (str "^" (repr (meta ~this-gs)) " "))))
7007
7008
7009
+ ;; IReduceKV
7010
+ (~'reduce-kv [~this-gs f# init#]
7011
+ (loop [res# init#
7012
+ fields# (seq ~this-gs)]
7013
+ (cond
7014
+ (reduced? res#) (deref res#)
7015
+ (seq fields#) (let [[k# v#] (first fields#)]
7016
+ (recur (f# res# k# v#)
7017
+ (rest fields#)))
7018
+ :else res#)))
7019
+
7008
7020
;; object
7009
7021
(~'__eq__ [~this-gs ~other-gs]
7010
7022
(or (identical? ~this-gs ~other-gs)
Original file line number Diff line number Diff line change 833
833
(is (= 6 (reduce (f) (range))))
834
834
(is (= 9 (reduce (f) 6 (range)))))))
835
835
836
+ (defrecord ReduceKVRecord [a b c])
837
+
836
838
(deftest reduce-kv-test
837
839
(testing "reduce-kv does not execute f if no elems in coll"
838
840
(let [a (atom false)]
864
866
(update :ks conj i)
865
867
(update :vs conj v)))
866
868
{:ks [] :vs []}
867
- [:a :b :c])))))
869
+ [:a :b :c]))))
870
+
871
+ (testing "works on records"
872
+ (is (= :reduced (reduce-kv (fn [acc k v]
873
+ (reduced :reduced))
874
+ {:ks #{} :vs #{}}
875
+ (->ReduceKVRecord 1 2 3))))
876
+
877
+ (let [rec (reduce-kv
878
+ (fn [acc k v]
879
+ (assoc acc k v))
880
+ (->ReduceKVRecord 0 1 2)
881
+ {:d 4 :e 5})]
882
+ (is (record? rec))
883
+ (is (instance? ReduceKVRecord rec)))
884
+
885
+ (are [res input] (= res (reduce-kv
886
+ (fn [acc k v]
887
+ (-> acc
888
+ (update :ks conj k)
889
+ (update :vs conj v)))
890
+ {:ks #{} :vs #{}}
891
+ input))
892
+ {:ks #{:a :b :c} :vs #{1 2 3}} (->ReduceKVRecord 1 2 3)
893
+ {:ks #{:a :b :c :d :e} :vs #{1 2 3 4 5}} (assoc (->ReduceKVRecord 1 2 3) :d 4 :e 5))))
868
894
869
895
(deftest fnil-test
870
896
(let [f (fnil (fn [x] x) :yes)]
You can’t perform that action at this time.
0 commit comments