-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Add take/takeRight/drop/dropRight to Chain #4694
base: main
Are you sure you want to change the base?
Conversation
@@ -308,13 +310,14 @@ sealed abstract class Chain[+A] extends ChainCompat[A] { | |||
arg match { | |||
case Wrap(seq) => | |||
if (count == 1) { | |||
lhs.append(seq.last) | |||
seq.last +: rhs |
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.
this was the bug. The rest of the changes are just optimizations to the code or scalacheck improvements.
} else { | ||
// count > 1 | ||
val taken = seq.take(count) | ||
// we may have not takeped all of count |
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.
hmm, out of curiosity, "takeped" – is it a typo or some slang I'm just not aware of? I also see "takeping" down below, so I guess it is intentional...
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.
no, I did drop
first and I did find and replace to take
and then changed the code. So, this was dropped
and dropping
with s/drop/take/
.
Thank you, these methods are really nice addition to Chain! One thing to clarify: |
if (newCount > 0) { | ||
// we have to keep takeping on the rhs | ||
go(newLhs, newCount, rhs, Chain.nil) |
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.
Shouldn't we eagerly exit with the newLhs
if rhs.isEmpty == true
?
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 don't think so, we have to check for empty anyway on the next call call of the loop. If we also check here we are checking twice. If we could ensure we never see Empty in the loop it would be worth it, but it would mean we would we have uglier code: we don't have a total match, we have one arm (Empty) that is unreachable. I don't think the performance win would be there and it would complicate the code.
What do you think?
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.
Okay, actually, I took this suggestion. I remembered we have NonEmpty
so we can recurse on that instead, that naturally pushes the check up to the places you suggest.
I still don't think it's any faster (since the Empty was the final check and always a terminal condition), but at least it's nice to be clear in the recursion that we are only operating on NonEmptyChain.
if (newCount > 0) { | ||
// we have to keep takeping on the rhs | ||
go(Chain.nil, newCount, lhs, newRhs) |
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.
Shouldn't we eagerly exit with the newRhs
if lhs.isEmpty == true
?
if (newCount > 0) { | ||
// we have to keep dropping on the rhs | ||
go(newCount, rhs, Chain.nil) |
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.
Shouldn't we eagerly exit with the Empty
if rhs.isEmpty == true
?
I reached for drop on Chain and realized we never implemented it however, we could implement it and using internal structure it can be more efficient than using iterators/toList.