let a = 0..<10, b = 0...10
a.underestimatedCount // 10
b.underestimatedCount // 11
zip(a, b).underestimatedCount // 0
Zip2Sequence can easily infer value from its underlying sequences.
That said, why is
Sequence.underestimatedCount a customization point in the first place?
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
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
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?
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”.