Skip to content

Improve traverseViaChain API#3535

Merged
johnynek merged 5 commits into
masterfrom
oscar/improveTraverseViaChain
Aug 3, 2020
Merged

Improve traverseViaChain API#3535
johnynek merged 5 commits into
masterfrom
oscar/improveTraverseViaChain

Conversation

@johnynek
Copy link
Copy Markdown
Contributor

follow up to #3521

In that PR, I added an API that consumes an Iterator. That is a bummer to have an API with a mutable arg, even if most people know that iterators must be considered with ownership semantics.

In fact, the first thing we do is materialize an IndexedSeq, so, why not just take an IndexedSeq and have callers materialize one if needed. This also removes duplication since Vector can share the same implementation now.

As an added bonus, you can use Chain.traverseViaChain(0 until 100000)(f) since Range is an IndexedSeq as well, which is nice.

It would be nice to get this in before 2.2.0 so we aren't stuck with the mutable API.

@johnynek johnynek requested a review from travisbrown July 27, 2020 21:19
@johnynek
Copy link
Copy Markdown
Contributor Author

@travisbrown I know I'm making your life a pain here with these PRs. I'm sorry. I do hope we can get this in and not have mima force us to keep an unneeded mutable API.

@travisbrown
Copy link
Copy Markdown
Contributor

No, this is great. Happy to review in the morning.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Jul 28, 2020

Codecov Report

Merging #3535 into master will increase coverage by 0.07%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master    #3535      +/-   ##
==========================================
+ Coverage   91.34%   91.41%   +0.07%     
==========================================
  Files         386      386              
  Lines        8592     8540      -52     
  Branches      241      241              
==========================================
- Hits         7848     7807      -41     
+ Misses        744      733      -11     

@johnynek
Copy link
Copy Markdown
Contributor Author

Okay, the 2.13 build brought up an interesting issue:

in 2.12, IndexedSeq is collection.IndexedSeq which may be mutable, which accepts ArrayBuffer. But that isn't safe for a lazy Applicative, because the computation may run later and the caller could mutate the input still. So, I added a wrapper which just makes an immutable.IndexedSeq from a mutable one when the caller promises not to mutate. Then, the public API can require an immutable IndexedSeq, which makes the contract clear.

This is probably a minor performance hit, but I imagine very very minimal (since the real meat of what traverse is doing is still the Eval and the applicative context I assume.

I think I'm happy with this now if you can take a look @travisbrown

@johnynek
Copy link
Copy Markdown
Contributor Author

johnynek commented Aug 3, 2020

@travisbrown what do you think about this one?

Copy link
Copy Markdown
Contributor

@travisbrown travisbrown left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine to me!

def wrapMutableIndexedSeq[A](m: mutable.IndexedSeq[A]): ImIndexedSeq[A] =
new WrappedIndexedSeq(m)

private[kernel] class WrappedIndexedSeq[A](m: mutable.IndexedSeq[A]) extends ImIndexedSeq[A] {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can never remember exactly how this works inside objects, but is there any reason to make this package-private (which is just public in the JVM API) instead of just private (which I think should be properly JVM-private)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not that I know of, I just copied the idiom below. Should I fix that up?

var first = true

foreach { a =>
foreachUntil { a =>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just miscellaneous clean-up, right, since foreach isn't used anywhere else?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. foreach is used exactly once and is private. Just use foreachUntil (or iterator).

@johnynek johnynek merged commit 763847f into master Aug 3, 2020
@travisbrown travisbrown added this to the 2.2.0-RC3 milestone Aug 15, 2020
@larsrh larsrh deleted the oscar/improveTraverseViaChain branch September 19, 2020 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants