-
Notifications
You must be signed in to change notification settings - Fork 3.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
Change LazyList
to always evaluate elements in order, and to have lazy empty-or-not status
#7558
Conversation
I will try to get this sometime later this week |
e496cd1
to
51cccd9
Compare
I think this is ready for review. Left a few overrides calling super with TODOs to revisit for potential minor laziness improvements. Because the overrides are there, they don't need to be addressed before 2.13.0. |
(I don't see Scaladoc changes, shouldn't there be some of those?) |
@SethTisue the docs were already hopelessly out of date - this PR doesn't make them any more so. Updating them is a task for scala/bug#11131. (translation: yes, there should be, but there aren'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.
Overridden methods that don't need to be overridden should be removed (and in some cases the superclass implementation could be improved!), but otherwise this looks like a great simplification.
if (res < 0) res else reversed.length - 1 - res | ||
} | ||
// TODO: maybe re-implement to be lazy with `that` if head of `that` never matches elements of `this` | ||
override def endsWith[B >: A](that: collection.Iterable[B]): Boolean = super.endsWith(that) |
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.
That could be arbitrarily expensive with all those comparisons that you otherwise could skip. I think the super implementation is the right one, and you should just remove this override and let it use the one from Seq. LinearSeq
as a whole could probably use an override that sped up some common scenarios, but this is the PR for that.
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.
Actually, you should fix the Seq
one to early-return false
if length
is less than that.length
. Lots of expensive stuff that could be skipped there. Also, to return true
if that
is empty (without evaluating the current collection at all, not even calling length
). This is better for everyone, but especially important for avoiding unnecessarily eager behavior in LazyList
.
if (res < 0) res else reversed.length - 1 - res | ||
} | ||
// TODO: maybe re-implement to be lazy with `that` if head of `that` never matches elements of `this` | ||
override def lastIndexOfSlice[B >: A](that: collection.Seq[B], end: Int): Int = |
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.
Just remove this method and let the superclass handle it. The Seq
implementation already special-cases IndexedSeq
and everything else; any benefits should be applied there. (It uses KMP searching, so it's nontrivial to improve on it.)
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.
@Ichoran after more thought, I'm thinking that this method (and endsWith
) should not attempt to preserve any laziness of that
- would you agree?
e66f0d9
to
881d844
Compare
@Ichoran I believe I have addressed your comments |
1692f21
to
a80adc6
Compare
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.
Changes LGTM--let's get this in and more thoroughly tested (e.g. with collections-laws)
Handled the merge conflict. Let's see if the tests go through. |
@Ichoran there's a test in |
4c5864e
to
ba2aa1b
Compare
ping |
nice to have this settled 🙂 |
LazyList
to always evaluate elements in order, and to have lazy empty-or-not status
Resolves scala/bug#11307.