Skip to content
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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

johnynek
Copy link
Contributor

@johnynek johnynek commented Jan 3, 2025

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.

@@ -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
Copy link
Contributor Author

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
Copy link
Contributor

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...

Copy link
Contributor Author

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/.

@satorg
Copy link
Contributor

satorg commented Jan 3, 2025

Thank you, these methods are really nice addition to Chain!

One thing to clarify: Chain uses Long for size. Would it make sense to make count parameter Long as well?
I realize it is unlikely that some one will ever hit Int limits in there, but size: Long implies that it is possible at least in theory.

Comment on lines 278 to 280
if (newCount > 0) {
// we have to keep takeping on the rhs
go(newLhs, newCount, rhs, Chain.nil)
Copy link
Member

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?

Copy link
Contributor Author

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?

Copy link
Contributor Author

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.

Comment on lines 321 to 323
if (newCount > 0) {
// we have to keep takeping on the rhs
go(Chain.nil, newCount, lhs, newRhs)
Copy link
Member

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?

Comment on lines 378 to 380
if (newCount > 0) {
// we have to keep dropping on the rhs
go(newCount, rhs, Chain.nil)
Copy link
Member

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants