I complained about it when it was released, but maybe now, that 3 is out, everyone is less absent minded. The way that IterableFactory
is implicitly convertible to a Factory
is really nice, syntax-wise. However it robs a collection from the ability to provide an optimised conversion to certain types. For example, consider a Ranking
: a Set
where order of elements matter, or a Seq
with unique elements. Due to sharing traits of both of the latter collections, while being neither, (i.e. fast contains
, positional access), overriden toSet
and toSeq
can return a very light wrapper in O(1)
. No such luck with to
though, as without really ugly reflection, I can’t recognize by a Factory
instance or class from what target collection type it came.
I think we have a IndexedSeq
, List
as well as HashSet
for the occasions when we want a specific implementation, for example for performance reasons. But Seq
is as abstract as it gets, unlike in other functional languages, exactly so we can have various implementations.
Why was it thought necessary to remove ReusableCBF
, which could be used to do various tricks like this? To be clear, I do not speak about CBF
in general, as it was clearly a design choice which I understand even if it makes me a sad panda. If only the implicit conversion target Factory
was always the same instance, or if Factory
exposed an Option[IterableFactory[_]]
, anything, we could see more such optimisations. Was it a conscious decision to prevent this sort of thing, or it just sort of happened? This would be an extremely minor, both source and binary compatible change to the library.
This is especially useful with various non-generic collections, especially domain-specific collections: if I have a dedicated collection type, then I typically want that runtime type to be preserved when the collection is used. However, methods like toSeq
are useful as a sort of explicit breakOut
from pre-2.13: they allow, at O(1)
, to share the internal structure o the dedicated collection, but circumventing any additional eatures and switching to a standard collection semantics (this of course works better for immutable implementations). It is also one of the reasons I am not super happy about deprecating overriding of various ‘toXxx’ methods, as it makes third-party implementations much worse integrated than they could.