Skip to content

Use foreach instead of manual iterator loops in fullIntersection - #83

Open
cheeseng wants to merge 1 commit into
dotty-staging:stdlib/full-intersectionfrom
artimahub:stdlib/full-intersection-artima-cs
Open

Use foreach instead of manual iterator loops in fullIntersection#83
cheeseng wants to merge 1 commit into
dotty-staging:stdlib/full-intersectionfrom
artimahub:stdlib/full-intersection-artima-cs

Conversation

@cheeseng

Copy link
Copy Markdown

fullIntersection traversed both this and that via
val it = iterator; while (it.hasNext) { ... it.next() ... }, even
though neither loop relies on iterator-specific behavior — each is a
single unconditional pass over its collection, and the two loops
don't interleave or share iterator state.

Switch both to foreach, so each collection dispatches to its own
native traversal (e.g. List walking cons cells directly, index-based
loops for array-backed types) instead of allocating an Iterator and
paying two virtual calls (hasNext/next) per element. Same change
already applied to deleted/updatedWith/splitAround.

No sizeHint added to any of the three builders (onlyThis, both,
onlyThat): the split between onlyThis and both depends entirely on
how much of this overlaps with that, and onlyThat's size depends
symmetrically on how much of that overlaps with this — neither is
knowable in advance, so a size hint would risk over-allocating
whichever builder turns out small rather than helping.

The method remains O(|this| + |that|) with two O(1)-average contains
checks (one per loop) — the theoretical floor for a 3-way set
partition, since deriving onlyThat requires a full pass over that
independent of what the first loop over this already determined.

No behavior changes.

Both loops walked their receiver via `val it = iterator; while
(it.hasNext) { ... it.next() ... }`, though neither needs
iterator-specific capability — each is a single unconditional pass
with no early exit or interleaving between them. Switch both to
foreach for native per-collection traversal instead of an allocated
Iterator plus two virtual calls (hasNext/next) per element, same as
the deleted/updatedWith/splitAround refactor.

No sizeHint added: the split between onlyThis/both and the size of
onlyThat are entirely data-dependent on the overlap between this and
that, so no reliable size estimate exists for any of the three
builders in advance.

No behavior changes.
@bishabosha

bishabosha commented Jul 24, 2026

Copy link
Copy Markdown

Well i think i would question this design - it is the same as an extension method that the original proposer was already doing, however they wanted to propose it as a more fundamental operation that can benefit from seeing the internals.

having said that - i dont see how

@bishabosha

Copy link
Copy Markdown

I asked ChatGPT so here is what is suggests for HAMT/CHAMP - https://chatgpt.com/share/6a638c28-31c4-83ed-8770-ace7891d9067

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.

2 participants