Support java collections & streams in for-do loops#15379
Conversation
…h extension methods in scala.Predef
|
I can reproduce the failure of |
|
Yes this test seems to be flaky, see #15371 (comment) |
|
Isn't this fixed with |
|
It is certainly a hassle and hard for beginners. Java collections already work fine with |
should be |
Work fine without, how? Welcome to Scala 3.2.0-RC1-bin-20220606-cec9aa3-NIGHTLY-git-cec9aa3 (11.0.15, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
scala> for x <- java.util.List.of(1, 2, 3) yield x
-- [E008] Not Found Error: -----------------------------------------------------
1 |for x <- java.util.List.of(1, 2, 3) yield x
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| value map is not a member of java.util.List[Int]
1 error found
scala> for x <- java.util.List.of(1, 2, 3); y <- List(x) yield y
-- [E008] Not Found Error: -----------------------------------------------------
1 |for x <- java.util.List.of(1, 2, 3); y <- List(x) yield y
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|value flatMap is not a member of java.util.List[Int], but could be made available as an extension method.
|
|One of the following imports might fix the problem:
|
| import collection.convert.ImplicitConversions.list asScalaBuffer
| import collection.convert.ImplicitConversionsToScala.list asScalaBuffer
| import collection.convert.ImplicitConversions.collection AsScalaIterable
| import collection.convert.ImplicitConversionsToScala.collection AsScalaIterable
| import collection.convert.ImplicitConversions.iterable AsScalaIterable
| import collection.convert.ImplicitConversionsToScala.iterable AsScalaIterable
|
1 error found |
|
It does work with scala> for x <- java.util.List.of(1).stream yield x
val res0: java.util.stream.Stream[Int] = java.util.stream.ReferencePipeline$3@6ac9b66b
scala> for x <- java.util.List.of(1).stream; y <- java.util.List.of(2).stream yield y
val res1: java.util.stream.Stream[Int] = java.util.stream.ReferencePipeline$7@129b0ed |
|
That's a good point @dwijnand |
|
I guess that extensions could be added for |
| def foreach(f: java.util.function.Consumer[T]): Unit = | ||
| it.forEach(f) | ||
|
|
||
| extension [T](s: java.util.stream.Stream[T]) |
There was a problem hiding this comment.
Should we also support IntStream and the other primitive streams?
There was a problem hiding this comment.
It we could support BaseStream (javadoc), which is the common interface above Stream, IntStream and all, it would be even better :)
edit: actually I got carried away: BaseStream doesn't provide any meaningful operation on its elements...
There was a problem hiding this comment.
I think it would be good to also support IntStream and the other primitive streams.
|
I really don't think this has its place in
There is no precedent for putting things in |
|
What if we make a type class like trait ForLoopSyntax[F[_]]:
def foreach[A](fa: F[A])(f: A => Unit): Unit
def map[A, B](fa: F[A])(f: A => B): F[B]
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]And if the compiler can't resolve the desugared The standard library could define some common givens, like for CompletableFuture and j.u.List. |
|
Isn't that a bit "overkill"? |
| def foreach(f: java.util.function.Consumer[T]): Unit = | ||
| it.forEach(f) | ||
|
|
||
| extension [T](s: java.util.stream.Stream[T]) |
There was a problem hiding this comment.
I think it would be good to also support IntStream and the other primitive streams.
| it.forEach(f) | ||
|
|
||
| extension [T](s: java.util.stream.Stream[T]) | ||
| def foreach(f: java.util.function.Consumer[T]): Unit = |
There was a problem hiding this comment.
If it is in Predef then foreach needs to be inline, since stdLibPatches/Predef.scala has no runtime equivalent. Or else we need a PR against 2.13 Predef instead.
Support java collections & streams in for-do loops by defining foreach extension methods in scala.Predef
Alternative to #15368