-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support java collections & streams in for-do loops #15379
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also support IntStream
and the other primitive streams?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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"? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think it's probably better to move this to some module that can be explicitly imported. Putting things in Predef
is a big step. For instance, what should happen on the JS platform?
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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