Who can dream up a way for me to combine Iterable and Traversable in a
backward (source)-compatible way?
Your challenge:
In Traversable, foreach is abstract
in Iterable, foreach is concrete, iterator is abstract
Iterable extends Traversable
So that means there's code out there like this:
new Traversable[Int] { def foreach[U](f: Int => U) = () }
And there's code out there like this:
new Iterable[Int] { def iterator = 1 to 10 iterator }
And there's code out there like this:
def f(xs: Traversable[Int]) = 10; f(Iterable(5)) ; f(Traversable(5))
I fear it cannot be done without some kind of magic wand (macros?
macros can do anything, right?)
- Traversable must have exactly one abstract method (foreach)
- Iterable must have exactly one as well (iterator)
- Iterable must extend Traversable (or must it? Maybe this is our in)
One might think OK, so we leave a "Traversable skeleton" in place, big
deal. Well it is a big deal, because the traits pass their type
constructor around with abandon and you can't fudge it, e.g.
trait GenIterable[+A]
extends GenIterableLike[A, GenIterable[A]]
with GenTraversableOnce[A]
with GenericIterableTemplate[A, GenIterable]
A Traversable skeleton won't stay quiet, he'll insist on a bunch of
supporting traits and all the goodness starts evaporating.
[scalacfork] trait Iterable[+A] extends Traversable[A] {
[scalacfork] ^
[scalacfork] /scala/trunk/src/library/scala/collection/GenIterable.scala:31:
error: polymorphic expression cannot be instantiated to expected type;
[scalacfork] found : [A(in method newBuilder)(in method
newBuilder)(in method newBuilder)(in method newBuilder)(in method
newBuilder)(in method newBuilder)(in method newBuilder)(in method
newBuilder)]scala.collection.mutable.Builder[A(in method
newBuilder)(in method newBuilder)(in method newBuilder)(in method
newBuilder)(in method newBuilder)(in method newBuilder)(in method
newBuilder)(in method newBuilder),Iterable[A(in method newBuilder)(in
method newBuilder)(in method newBuilder)(in method newBuilder)(in
method newBuilder)(in method newBuilder)(in method newBuilder)(in
method newBuilder)]]
[scalacfork] required: scala.collection.mutable.Builder[A(in method
newBuilder)(in method newBuilder)(in method newBuilder)(in method
newBuilder)(in method newBuilder)(in method newBuilder)(in method
newBuilder)(in method newBuilder),scala.collection.GenIterable[A(in
method newBuilder)(in method newBuilder)(in method newBuilder)(in
method newBuilder)(in method newBuilder)(in method newBuilder)(in
method newBuilder)(in method newBuilder)]]
I fear it cannot be done without some kind of magic wand (macros?
macros can do anything, right?)
BURN THE HERETIC
--
Daniel C. Sobral
I travel to the future all the time.
I'm just exploring. I think either the gains will speak for
themselves or they won't.
I'm a fan of splitting external vs. Internal iterator abstraction so one does not inherit the other...