Skip to content
Browse files

Fix count for non-counted collections, remove ICounted from Cons

Since default no longer gets extended to ICounted, the original
implementation of cljs.core/count no longer works on LazySeq
instances.

This patch takes the approach of checking whether the given collection
is counted and either calling -count or a linear traversal
helper (which rolls over to -count as soon as possible).

The implementation of ICounted on Cons is now unnecessary and has been
removed, so that things for which counted? returns true really do
provide constant-time count.
  • Loading branch information...
1 parent 73a5684 commit 0ad5556531325d03746f05845dcd26acdc716ef7 @michalmarczyk michalmarczyk committed with David Nolen May 2, 2012
Showing with 11 additions and 9 deletions.
  1. +11 −9 src/cljs/cljs/core.cljs
View
20 src/cljs/cljs/core.cljs
@@ -569,11 +569,20 @@ reduces them without incurring seq initialization"
[coll]
(-empty coll))
+(declare counted?)
+
+(defn- accumulating-seq-count [coll acc]
+ (if (counted? coll) ; assumes nil is counted, which it currently is
+ (+ acc (-count coll))
+ (recur (next coll) (inc acc))))
+
(defn count
"Returns the number of items in the collection. (count nil) returns
0. Also works on strings, arrays, and Maps"
[coll]
- (-count coll))
+ (if (counted? coll)
+ (-count coll)
+ (accumulating-seq-count coll 0)))
(defn nth
"Returns the value at the index. get returns nil if index out of
@@ -1428,14 +1437,7 @@ reduces them without incurring seq initialization"
(-hash [coll] (caching-hash coll hash-coll __hash))
ISeqable
- (-seq [coll] coll)
-
- ICounted
- (-count [coll]
- (loop [s (seq coll) n 0]
- (if s
- (recur (next s) (inc n))
- n))))
+ (-seq [coll] coll))
(defn cons
"Returns a new seq where x is the first element and seq is the rest."

0 comments on commit 0ad5556

Please sign in to comment.
Something went wrong with that request. Please try again.