underestimatedCount on zip

let a = 0..<10, b = 0...10

a.underestimatedCount // 10
b.underestimatedCount // 11
zip(a, b).underestimatedCount // 0

I think Zip2Sequence can easily infer value from its underlying sequences.

That said, why is Sequence.underestimatedCount a customization point in the first place?

1 Like

That's true. underestimatedCount isn't implemented on Zip2Sequence because it was simply forgotten back then.


Sequence.underestimatedCount really shouldn’t be customization point. People too easily forget about it.

The upcoming proposal should fix this.

This is plausibly worth fixing via a bug-fix PR separate from the referenced SE proposal, if anyone has the inclination to do so.

Filed SR-9570 and created apple/swift#21530.


It's important to be able to customize the underestimate. For example, lazy non-random-access collections (like lazy filter or flatMap) return 0 not count (the default underestimate for collections) because lazy collections making unexpected multiple passes to compute their count can be problematic.


It has to be a customization point; it's the only Sequence method that doesn't lead (supposedly) to vending elements, and so can work with single-pass implementations.

What if we remove only Sequence‘s default implementation instead?
It seems to me that it causes a lot of conforming types to forget about it, especially when a lot of types are able to do better than 0.

I’m not sure I follow what you’re trying to say, the type’s designer should already know (or be warned from the protocol description) that the underestimatedCount’s getter shouldn’t consume the sequence. Whether or not it’s a customization point seem irrelevant to me.

Wouldn't that cause a backwards-compatibility problem, where existing types suddenly have to implement the property?

underestimatedCount and makeIterator() are the primitive operations of Sequence; all other operations are done in terms of those two. How could underestimatedCount be implemented if it becomes non-extensible? There are no other non-consuming operations.

I think some people in this thread are using “customization point” to mean “protocol member” and some people are using it to mean “protocol member with default implementation”.