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
StreamWithFilter's map and flatMap evaluate one more element than necessary #9134
Comments
Imported From: https://issues.scala-lang.org/browse/SI-9134?orig=1 |
@ms-tg said: Essentially, I argue that the WithFilter implementation should absolutely not be re-implementing map/flatMap/foreach, and should implement in terms of a call to #filter followed by the specific call. Thoughts? I'm happy to add a test of this behavior to the same PR to try to see if we can solve both problems at the same time? |
@ms-tg said: @adriaanm just merged my fix (scala/scala@198c201) to #8990. As you can see in the linked fix, |
@ms-tg said: Specifically, here's the test that represents the problem you described: |
Aurel Paulovič (aurel.paulovic) said: I was not able to run the 2.12.x version of it, but since the test fails for me in 2.11.5, and it does not in 2.12.x, it should be ok. |
Processing a
Stream
using itswithFilter
method evaluates one more element than necessary. When processing aStream
using thefilter
method, only the necessary elements are evaluated.Having a simple
Stream
of natural numbers:Calling
map
on aStream
filtered usingfilter
vs.withFilter
produces the same result, however,withFilter
evaluates one more element:The behaviour is caused by a call to
tail
in StreamWithFilter.map and the same problem is inflatMap
.This is a bug, because the semantics of using
filter
andwithFilter
should be the same;withFilter
should be only an optimization. Moreover, the right behaviour is that of thefilter
because theStream
operations should be as lazy as possible and in this case there is no reason to evaluate the next element.As a possible use case where the current behaviour of
withFilter
manifests as a bug consider the following: having a possibly endless stream of attempts to transactionally perform some computation, try to commit it and if the commit is not successful, perform the transaction anew with new current snapshot of data.The above code will use
withFilter
and possibly perform and commit two times. The expected behaviour is that the transaction would be performed and attempted to commit only until it successfully commits the first time.The text was updated successfully, but these errors were encountered: