scala/scala-collection-compat

IterableOnce.iterator not available in Scala 2.12.x

borice opened this issue · 5 comments

Scala 2.12:

val t: TraversableOnce[Int] = List(1,2,3)
val tm = t.map(_ + 1)

migrating the above contrived example to Scala 2.13 (according to the @deprecated instructions) leads to:

Scala 2.13:

import scala.collection.compat.IterableOnce

val t: IterableOnce[Int] = List(1,2,3)
val tm = t.iterator.map(_ + 1)  // since t.map was deprecated, requiring t.iterator.map

Trying to cross-compile the Scala 2.13 version to 2.12 using scala-collection-compat, we get a compilation error complaining about .iterator not being a member of TraversableOnce[Int]. Indeed, .iterator is only available on IterableOnce, but not in TraversableOnce. However, TraversableOnce does have a .toIterator method (but it's deprecated in IterableOnce).

Adding a .iterator extension method to TraversableOnce in scala-collection-compat for Scala 2.12- that calls .toIterator would solve the problem.

  • Per Seth, the surface area of impact should look similar to #566
  • Confirmed in manual/external code test that this issue is still valid

I may have misspoke.

I don't believe the import as stated works. In order to get the implicit conversions that power this library, you would need a wildcard import.

import scala.collection.compat._

Having such an import makes the .iterator code work.

Moreover I believe the functionality already exists here https://github.com/scala/scala-collection-compat/blob/main/compat/src/main/scala-2.11_2.12/scala/collection/compat/PackageShared.scala#L416

Voting to close this one as not an issue.

@borice not sure if you're still around, but do you agree...?

% scala-cli -S 2.12.18 --dep org.scala-lang.modules::scala-collection-compat:2.10.0
Welcome to Scala 2.12.18 (OpenJDK 64-Bit Server VM, Java 17.0.7).
Type in expressions for evaluation. Or try :help.

scala> import scala.collection.compat._
import scala.collection.compat._

scala> val t: IterableOnce[Int] = List(1,2,3)
t: collection.compat.IterableOnce[Int] = List(1, 2, 3)

scala> val tm = t.iterator.map(_ + 1)
tm: Iterator[Int] = <iterator>

scala> tm.toList
res0: List[Int] = List(2, 3, 4)

@mcanlas thanks for looking into it!

@borice if you're seeking to avoid a wildcard import, the following set of imports is also sufficient:

import scala.collection.compat.IterableOnce
import scala.collection.compat.toTraversableOnceExtensionMethods