File tree Expand file tree Collapse file tree 3 files changed +48
-4
lines changed Expand file tree Collapse file tree 3 files changed +48
-4
lines changed Original file line number Diff line number Diff line change @@ -59,6 +59,13 @@ Like multimethods but multidecorators.
5959(assert (= [] (func ::f )))
6060```
6161
62+ ## Memoization
63+
64+ ``` clojure
65+ (defn -main []
66+ (alter-var-root #'func md/memoize-multi))
67+ ```
68+
6269## Development
6370
6471```
Original file line number Diff line number Diff line change 4141 f (method @iregistry tag initial)]
4242 (apply f obj args))))))
4343
44+ (defn memoize-multi [multi]
45+ (case (:type (multi ))
46+ :memoized multi
47+ :dynamic (let [{:keys [iregistry
48+ dispatch
49+ initial]} (multi )
50+ registry @iregistry
51+ mem-method (memoize method)]
52+ (fn
53+ ([] {:type :memoized
54+ :registry registry
55+ :initial initial
56+ :dispatch dispatch})
57+ ([obj & args]
58+ (let [tag (apply dispatch obj args)
59+ f (mem-method registry tag initial)]
60+ (apply f obj args)))))))
61+
4462(defn ^{:style/indent :defn } decorate [multi tag decorator]
45- (let [state (multi )
46- iregistry (:iregistry state)]
47- (swap! iregistry assoc tag decorator)
48- multi))
63+ (case (:type (multi ))
64+ :dynamic (let [state (multi )
65+ iregistry (:iregistry state)]
66+ (swap! iregistry assoc tag decorator)
67+ multi)))
Original file line number Diff line number Diff line change 3333 (t/is (= [] (multi ::f )))
3434 (t/is (= [:a :b :c :d 's] (multi `s)))
3535 #?(:clj (t/is (= [:a :b :c :d :obj ] (multi String))))))
36+
37+ (t/deftest memoization
38+ (let [multi (doto (md/multi identity (constantly []))
39+ (md/decorate ::a (fn [super obj] (conj (super obj) :a )))
40+ (md/decorate ::b (fn [super obj] (conj (super obj) :b )))
41+ (md/decorate ::c (fn [super obj] (conj (super obj) :c )))
42+ (md/decorate ::d (fn [super obj] (conj (super obj) :d )))
43+ (md/decorate `s (fn [super obj] (conj (super obj) 's)))
44+ #?(:clj (md/decorate Object (fn [super obj] (conj (super obj) :obj )))))
45+ mem-multi (md/memoize-multi multi)]
46+ (doseq [_ (range 2 )]
47+ (t/is (= [:a ] (mem-multi ::a )))
48+ (t/is (= [:a :b ] (mem-multi ::b )))
49+ (t/is (= [:a :c ] (mem-multi ::c )))
50+ (t/is (= [:a :b :c :d ] (mem-multi ::d )))
51+ (t/is (= [] (mem-multi ::f )))
52+ (t/is (= [:a :b :c :d 's] (mem-multi `s)))
53+ #?(:clj (t/is (= [:a :b :c :d :obj ] (mem-multi String)))))))
You can’t perform that action at this time.
0 commit comments