Skip to content

Fix iterator / iterable typedefs, add generator typedefs#8355

Merged
cknitt merged 7 commits intomasterfrom
iterators
Apr 18, 2026
Merged

Fix iterator / iterable typedefs, add generator typedefs#8355
cknitt merged 7 commits intomasterfrom
iterators

Conversation

@cknitt
Copy link
Copy Markdown
Member

@cknitt cknitt commented Apr 18, 2026

Introduce Explicit Iterator, Iterable, And Generator Types

Summary

This PR clarifies the stdlib iterator model so that it matches modern JavaScript more closely and gives each exposed module a distinct purpose.

This is a breaking change.

It is also a precondition for upcoming work on for..of loops.

Motivation

Before this change, the sync iterator story blurred together several different runtime concepts:

  • a bare iterator protocol object
  • an iterable value
  • a value that is both iterable and iterator-shaped
  • a built-in iterator object that inherits from Iterator.prototype and has iterator helper methods

In practice those are not the same thing.

For example:

  • a custom object with only next() is an iterator, but not iterable
  • a custom object with next() and [Symbol.iterator]() is an iterable iterator, but it still may not have helper methods like map() or toArray()
  • Array.values() and Map.entries() return built-in iterator objects that do have that helper-enabled runtime identity in modern runtimes
  • generator objects are also built-in iterator objects and should line up with that same model

The goal of this PR is to make those differences visible in the API instead of implicitly treating them as one thing.

Type Guide

Overview

Type Short explanation
Iterable.t<'a> Any value that can be iterated with for..of or consumed by Array.from.
Iterator.t<'yield, 'return, 'next> The plain sync iterator protocol as modeled in our bindings: next(), yielded values, final return values, and values passed back into iteration.
IterableIterator.t<'yield, 'return, 'next> A sync iterator that is also iterable, but is not assumed to have iterator helper methods.
IteratorObject.t<'yield, 'return, 'next> A built-in sync iterator object that inherits from Iterator.prototype, including iterator helper methods.
Generator.t<'yield, 'return, 'next> A JavaScript generator object, with iterable behavior, iterator behavior, and generator-specific methods.
AsyncIterable.t<'yield> Any value that can be consumed with for await..of.
AsyncIterator.t<'yield, 'return, 'next> The plain async iterator protocol as modeled in our bindings: next(), yielded values, final return values, and values passed back into iteration.
AsyncIterableIterator.t<'yield, 'return, 'next> An async iterator that is also async iterable.
AsyncGenerator.t<'yield, 'return, 'next> A JavaScript async generator object.

Breaking Changes In This PR

Stdlib.Iterator.t now takes three type parameters

Stdlib.Iterator.t used to take one type parameter and now takes three:

  • Iterator.t<'yield, 'return, 'next>

The parameters mean:

  • 'yield: the type produced while iterating
  • 'return: the final value when iteration completes
  • 'next: the type that can be passed back into iteration via next(value)

This matches the richer iterator model introduced in this PR and gives generators and protocol-level iterators a precise type for all three parts of the iteration protocol.

Raw iterator results are now normalized explicitly

JavaScript iterator results are slightly looser than the normalized model we want to expose in ReScript.

In particular, a yielded iterator result may omit done, and that is still supposed to behave like a yield rather than completion.

This PR therefore normalizes raw JavaScript iterator results before exposing them through Iterator.result and AsyncIterator.result.

There is still a low-level raw representation for internal use and protocol-level interop, but it is not meant to be the main public story.

The important user-facing change is that next() and nextValue() now behave correctly for protocol-compliant iterators even when yielded results omit done.

Built-in sync iterator APIs now return IteratorObject.t

The following APIs are retargeted from protocol-only iterator types to IteratorObject.t:

  • Array.entries
  • Array.values
  • Map.keys
  • Map.values
  • Map.entries
  • Set.values

Motivation:
These are built-in iterator objects in modern runtimes, so the types should reflect the helper methods that are actually present.

Relationship To TypeScript

TypeScript distinguishes between:

  • Iterator
  • Iterable
  • IterableIterator
  • IteratorObject
  • specialized built-in iterator names such as ArrayIterator, MapIterator, and SetIterator

This PR follows the same core distinction between protocol-only iterators and runtime-produced helper-enabled iterator objects, but deliberately does not expose TS-only specializations such as ArrayIterator, MapIterator, or SetIterator.

Docs

This PR also cleans up the .resi docs:

  • add clearer module-level descriptions
  • add MDN links to the iterator-related modules
  • update examples so built-in iterators use IteratorObject where appropriate

Comment thread tests/gentype_tests/stdlib-no-shims/src/index.ts Dismissed
Comment thread tests/gentype_tests/stdlib-no-shims/src/index.ts Dismissed
Comment thread tests/gentype_tests/stdlib-no-shims/src/index.ts Dismissed
Comment thread tests/gentype_tests/stdlib-no-shims/src/index.ts Dismissed
Comment thread tests/gentype_tests/stdlib-no-shims/src/index.ts Dismissed
Comment thread tests/gentype_tests/stdlib-no-shims/src/index.ts Dismissed
Comment thread tests/gentype_tests/stdlib-no-shims/src/index.ts Dismissed
Comment thread tests/gentype_tests/stdlib-no-shims/src/index.ts Fixed
Comment thread tests/gentype_tests/stdlib-no-shims/src/index.ts Fixed
Comment thread tests/gentype_tests/stdlib-no-shims/src/index.ts Fixed
@cknitt
Copy link
Copy Markdown
Member Author

cknitt commented Apr 18, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 353a590135

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/@rescript/runtime/Stdlib_Generator.resi
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 18, 2026

Open in StackBlitz

rescript

npm i https://pkg.pr.new/rescript@8355

@rescript/darwin-arm64

npm i https://pkg.pr.new/@rescript/darwin-arm64@8355

@rescript/darwin-x64

npm i https://pkg.pr.new/@rescript/darwin-x64@8355

@rescript/linux-arm64

npm i https://pkg.pr.new/@rescript/linux-arm64@8355

@rescript/linux-x64

npm i https://pkg.pr.new/@rescript/linux-x64@8355

@rescript/runtime

npm i https://pkg.pr.new/@rescript/runtime@8355

@rescript/win32-x64

npm i https://pkg.pr.new/@rescript/win32-x64@8355

commit: a0a3075

@cknitt
Copy link
Copy Markdown
Member Author

cknitt commented Apr 18, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7c225b3eaa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/@rescript/runtime/Stdlib_IteratorObject.res Outdated
@cknitt
Copy link
Copy Markdown
Member Author

cknitt commented Apr 18, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6bfdda1bde

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/@rescript/runtime/Stdlib_Iterator.res
@cknitt
Copy link
Copy Markdown
Member Author

cknitt commented Apr 18, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@cknitt cknitt marked this pull request as ready for review April 18, 2026 13:33
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The documentation looks good, and I like the way the usage looks in the examples.

Comment thread compiler/ml/predef.ml
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is iterable the only thing we need to add to predefs? Is that enough to cover everything we need?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

For the for..of loop (upcoming PR), yes, but as there will also be the for await..of loop, we might as well add asyncIterable now, too.

Copy link
Copy Markdown
Member

@zth zth left a comment

Choose a reason for hiding this comment

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

Haven't gotten into great depth because I don't know the subject too well, but looks good to me!

Comment thread tests/gentype_tests/stdlib-no-shims/src/index.ts Dismissed
Comment thread tests/gentype_tests/stdlib-no-shims/src/index.ts Dismissed
Comment thread tests/gentype_tests/stdlib-no-shims/src/index.ts Dismissed
@cknitt cknitt merged commit 4bf0cd3 into master Apr 18, 2026
32 checks passed
@cknitt cknitt deleted the iterators branch April 18, 2026 15:43
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