aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/clojure/contrib/accumulators.clj100
-rw-r--r--src/clojure/contrib/accumulators/examples.clj6
2 files changed, 53 insertions, 53 deletions
diff --git a/src/clojure/contrib/accumulators.clj b/src/clojure/contrib/accumulators.clj
index e3cd52c8..bbbcd64f 100644
--- a/src/clojure/contrib/accumulators.clj
+++ b/src/clojure/contrib/accumulators.clj
@@ -1,7 +1,7 @@
;; Accumulators
;; by Konrad Hinsen
-;; last updated February 26, 2009
+;; last updated February 27, 2009
;; This module defines various accumulators (list, vector, map,
;; sum, product, counter, and combinations thereof) with a common
@@ -186,14 +186,14 @@
"An empty minimum accumulator. Only numbers can be added.")
;
-; Numeric range accumulator
+; Numeric min-max accumulator
; (combination of minimum and maximum)
;
(deftype min-max-type
(min-max min max))
-(defvar empty-range (min-max nil nil)
- "An empty range accumulator, combining minimum and maximum.
+(defvar empty-min-max (min-max nil nil)
+ "An empty min-max accumulator, combining minimum and maximum.
Only numbers can be added.")
(defmethod combine min-max-type
@@ -213,63 +213,63 @@
;
; Counter accumulator
;
-(deftype counter-type
- (counter map))
+(let [type-tag ::counter
+ meta-map {:type type-tag}]
-(defvar empty-counter (counter {})
- "An empty counter accumulator. Its value is a map that stores for
- every item the number of times it was added.")
+ (defvar empty-counter (with-meta {} meta-map)
+ "An empty counter accumulator. Its value is a map that stores for
+ every item the number of times it was added.")
-(defmethod combine counter-type
- [v & vs]
- (letfn [add-item [cntr [item n]]
- (assoc cntr item (+ n (get cntr item 0)))
- add-two [c1 c2] (reduce add-item c1 c2)]
- (counter (reduce add-two (get-value v) (map get-value vs)))))
+ (defmethod combine type-tag
+ [v & vs]
+ (letfn [add-item [counter [item n]]
+ (assoc counter item (+ n (get counter item 0)))
+ add-two [c1 c2] (reduce add-item c1 c2)]
+ (reduce add-two v vs)))
-(defmethod add counter-type
- [v e]
- (let [cntr (get-value v)]
- (counter (assoc cntr e (inc (get cntr e 0))))))
+ (defmethod add type-tag
+ [v e]
+ (assoc v e (inc (get v e 0)))))
;
; Counter accumulator with total count
;
-(deftype counter-with-total-type
- (counter-with-total map))
-(derive counter-with-total-type counter-type)
+(let [type-tag ::counter-with-total
+ meta-map {:type type-tag}]
-(defvar empty-counter-with-total (counter-with-total {:total 0})
- "An empty counter-with-total accumulator. It works like the counter
- accumulator, except that the total number of items added is stored as the
- value of the key :totall.")
+ (derive type-tag ::counter)
-(defmethod add counter-with-total-type
- [v e]
- (let [cntr (get-value v)]
- (counter-with-total
- (assoc cntr e (inc (get cntr e 0))
- :total (inc (:total cntr))))))
+ (defvar empty-counter-with-total
+ (with-meta {:total 0} meta-map)
+ "An empty counter-with-total accumulator. It works like the counter
+ accumulator, except that the total number of items added is stored as the
+ value of the key :totall.")
+
+ (defmethod add type-tag
+ [v e]
+ (assoc v e (inc (get v e 0))
+ :total (inc (:total v)))))
;
; Accumulator n-tuple
;
-(deftype tuple-type
- (tuple accs))
-
-(defn empty-tuple
- "Returns an accumulator tuple with the supplied empty-accumulators
- as its value. Accumulator tuples consist of several accumulators that
- work in parallel. Added items must be sequences whose number of elements
- matches the number of sub-accumulators."
- [empty-accumulators]
- (tuple empty-accumulators))
-
-(defmethod combine tuple-type
- [& vs]
- (tuple (map combine (get-value vs))))
-
-(defmethod add tuple-type
- [v e]
- (tuple (map add (get-value v) e)))
+(let [type-tag ::tuple
+ meta-map {:type type-tag}
+ make (fn [s] (with-meta (into [] s) meta-map))]
+
+ (defn empty-tuple
+ "Returns an accumulator tuple with the supplied empty-accumulators
+ as its value. Accumulator tuples consist of several accumulators that
+ work in parallel. Added items must be sequences whose number of elements
+ matches the number of sub-accumulators."
+ [empty-accumulators]
+ (make empty-accumulators))
+
+ (defmethod combine ::tuple
+ [& vs]
+ (make (map combine vs)))
+
+ (defmethod add ::tuple
+ [v e]
+ (make (map add v e))))
diff --git a/src/clojure/contrib/accumulators/examples.clj b/src/clojure/contrib/accumulators/examples.clj
index ee0727e9..a7e9f640 100644
--- a/src/clojure/contrib/accumulators/examples.clj
+++ b/src/clojure/contrib/accumulators/examples.clj
@@ -63,9 +63,9 @@
m2 (add-items empty-minimum [(/ 1 2)])]
(combine m1 m2))
-; Range accumulator: combination of minimum and maximum
-(let [m1 (add-items empty-range [2 3])
- m2 (add-items empty-range [(/ 1 2)])]
+; Min-max accumulator: combination of minimum and maximum
+(let [m1 (add-items empty-min-max [2 3])
+ m2 (add-items empty-min-max [(/ 1 2)])]
(combine m1 m2))
; String accumulator: combine is concatenation