Conversation
#246 Adds TaskSeqDynamicInfo<'T> and TaskSeqDynamic<'T> types that implement the dynamic (ResumptionDynamicInfo-based) execution path for taskSeq computation expressions. This fixes the NotImplementedException raised when taskSeq is used in contexts where the F# compiler cannot emit static resumable code, such as F# Interactive (FSI) or top-level functions. Key changes: - TaskSeqDynamicInfo<'T>: concrete ResumptionDynamicInfo subclass that handles MoveNext transitions (same logic as the static MoveNextMethodImpl) - TaskSeqDynamic<'T>: reference-type IAsyncEnumerable implementation using the dynamic path, with proper cloning support for re-enumeration - TaskSeqBuilder.Run: else-branch now creates TaskSeqDynamic instead of raising - taskSeqDynamic: new CE builder (inherits TaskSeqBuilder) and module value; identical to taskSeq in compiled code, uses dynamic path in FSI - 24 new tests covering: empty, single/multi yield, for/while loops, async bind, Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
dsyme
approved these changes
Apr 7, 2026
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 This is an automated pull request from Repo Assist, an AI assistant.
Closes #246
Summary
This PR implements the dynamic (FSI-compatible) resumable code path for
taskSeqcomputation expressions, fixing theNotImplementedExceptionthat was raised whenevertaskSeqwas used in F# Interactive or any context where the F# compiler cannot emit static resumable code.Root Cause
The
TaskSeqBuilder.Runmethod has two branches controlled by__useResumableCode:__stateMachineto generate a static state machine structNotImplementedExceptionFix
New types added
TaskSeqDynamicInfo<'T>ResumptionDynamicInfosubclass. OverridesMoveNextto drive the resumption function and handle yield/await/completion—same logic as the staticMoveNextMethodImpl.TaskSeqDynamic<'T>IAsyncEnumerable<'T>implementation for the dynamic path. Stores_initialResumptionFuncinstead of a compiler-generated machine struct, with correct cloning for re-enumeration.Builder changes
TaskSeqBuilder.Runelsebranch now creates aTaskSeqDynamic<'T>instead of raising.TaskSeqDynamicBuildertype (inheritsTaskSeqBuilderwith no overrides—the baseRunalready handles both paths).taskSeqDynamicCE value exported fromTaskSeqDynamicBuildermodule.Suppression
#nowarn "3513"added toTaskSeqBuilder.fs—theResumableCode.Invokecall in the dynamicelsebranch is an intentional use of resumable code as a regular delegate.Trade-offs
TaskSeqDynamic<'T>) vs. the static path's struct. This is acceptable since the dynamic path is only used in FSI.taskSeqDynamicis functionally identical totaskSeqin compiled code (uses the same static path). Its only advantage overtaskSeqis that it documents intent for code meant to run in FSI.Test Status
✅ Build: 0 warnings, 0 errors (Release)
✅ Fantomas: formatting check passes
✅ Tests: 5093 passed (24 new + 5069 existing), 2 skipped, 0 failed
New tests cover: empty sequence, single/multi yield,
for/whileloops,Task/Asyncbind,yield!fromseq/taskSeq/taskSeqDynamic,tryWith,tryFinally,use, cancellation, re-enumeration, large sequences, nested loops.