Skip to content

[Repo Assist] perf: use while! in iter/fold/reduce/mapFold/tryLast/Drop/Truncate#382

Draft
github-actions[bot] wants to merge 1 commit intomainfrom
repo-assist/perf-while-bang-cleanup-20260409-5ddbcb4cb509276b
Draft

[Repo Assist] perf: use while! in iter/fold/reduce/mapFold/tryLast/Drop/Truncate#382
github-actions[bot] wants to merge 1 commit intomainfrom
repo-assist/perf-while-bang-cleanup-20260409-5ddbcb4cb509276b

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions bot commented Apr 9, 2026

🤖 This is an automated pull request from Repo Assist, an AI assistant.

Summary

This PR replaces the manual go-flag + initial-MoveNext pre-advance pattern with idiomatic while! in six functions: iter, fold, reduce, mapFold, tryLast, and the Drop/Truncate cases of skipOrTake.

The pattern being replaced

Before (in iter, fold, reduce, mapFold, tryLast):

let mutable go = true
let! step = e.MoveNextAsync()
go <- step

while go do
    // body
    let! step = e.MoveNextAsync()
    go <- step

After:

while! e.MoveNextAsync() do
    // body

This matches the pattern already established by sum, sumBy, average, averageBy, lengthBy, lengthBeforeMax, and others.

Changes

Function Before After
iter manual go flag, initial pre-advance while! e.MoveNextAsync() per branch
fold manual go flag, initial pre-advance while! e.MoveNextAsync() per branch
reduce manual go flag, second pre-advance after first-element check while! e.MoveNextAsync() per branch
mapFold manual go flag, initial pre-advance while! e.MoveNextAsync() per branch
tryLast manual go flag, initial pre-advance while! e.MoveNextAsync()
skipOrTake/Drop pos counter with inner if pos < count i < count as loop guard, if cont for rest
skipOrTake/Truncate pos counter with inner if pos < count yielded < count as loop guard

Benefits

  • Removes one mutable bool per function (the go flag)
  • Removes the initial pre-advance let! step = e.MoveNextAsync(); go <- step before the loop
  • Hoists the match action/folder/... dispatch outside the while loop in iter and fold (it was already outside in the original, but the new form makes it clearer that each branch owns its own tight loop)
  • Unifies style across the module — new contributors see one consistent idiom

Scope

All changes are purely internal — no public API or behaviour change.

Trade-offs

  • None. This is a straightforward pattern replacement with identical semantics, verified by the full test suite.

Test Status

Build: 0 warnings, 0 errors (Release)
Fantomas: formatting check passes
Tests: 5093 passed, 2 skipped, 0 failed

Generated by 🌈 Repo Assist, see workflow run. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@7ee2b60744abf71b985bead4599640f165edcd93

Replace the manual 'go' flag + initial MoveNextAsync pre-advance pattern
with while! in iter, fold, reduce, mapFold, tryLast, and the Drop/Truncate
cases in skipOrTake.

The old pattern:
  let! step = e.MoveNextAsync()
  go <- step
  while go do
    ...
    let! step = e.MoveNextAsync()
    go <- step

becomes:
  while! e.MoveNextAsync() do
    ...

This matches the pattern already established by sum, sumBy, average,
averageBy, lengthBy, etc. Benefits:
- Removes one mutable bool (go) per function
- Removes the initial redundant pre-advance call before the loop
- Unifies style across the module

Also simplifies the Drop and Truncate loop bodies to use explicit
i/yielded counters instead of a pos variable with an inline if/else.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

0 participants