Skip to content

Conversation

cknitt
Copy link
Member

@cknitt cknitt commented Sep 13, 2025

My assistant and I created a very basic implementation of for...of loops that only works on arrays for now.

Will need to think about how to support iterators later.

@cknitt cknitt marked this pull request as draft September 13, 2025 06:56
(sub.expr sub e3)
| Pexp_for_of (_pat, _array_expr, _body_expr) ->
(* Convert for...of to an extension since it doesn't exist in old AST *)
extension ~loc ~attrs (Location.mkloc "rescript.for_of" loc, PStr [])
Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure what needs to be done here.
How can we map to ast0 in such a way that we can map it back?

Copy link
Member

Choose a reason for hiding this comment

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

Extension sounds reasonable.

2 │

Did you forget a `in` here?
I'm not sure what to parse here when looking at "eof".
Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure what to do about this change in the test output here

5 │ Js.log("for")
6 │ }

consecutive statements on a line must be separated by ';' or a newline
Copy link
Member Author

Choose a reason for hiding this comment

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

or here

Copy link

pkg-pr-new bot commented Sep 13, 2025

Open in StackBlitz

rescript

npm i https://pkg.pr.new/rescript-lang/rescript@7887

@rescript/darwin-arm64

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

@rescript/darwin-x64

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

@rescript/linux-arm64

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

@rescript/linux-x64

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

@rescript/runtime

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/runtime@7887

@rescript/win32-x64

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

commit: 8b779af

@cknitt cknitt requested a review from cristianoc September 13, 2025 12:51
@cknitt cknitt changed the title Very basic implementation of for..of loops [Poc] for..of loops Sep 17, 2025
@cknitt cknitt changed the title [Poc] for..of loops [PoC] for..of loops Sep 17, 2025
@cknitt cknitt force-pushed the for-of branch 2 times, most recently from c508d37 to 77f91d8 Compare September 18, 2025 19:05
@cristianoc
Copy link
Collaborator

The big questions were language design related ones, rather than implementation.
There are many ways to go about this.
@cometkim still got some design notes from the retreat? This could be the right time to do some more text-based discussion before the code-based one.

@cometkim
Copy link
Member

cometkim commented Sep 19, 2025

Frankly, importing the JavaScript for-of syntax as-is doesn't sound all that appealing. It's not much different from embedding %raw.

Here are my thoughts on designing for loops:

  1. Since iterators are essential in JavaScript, we need to define iterator semantics before design the synyax. The syntax follows.
  2. Without control flow support, the for-of syntax itself isn't very useful. With good control semantics, the simple iterator protocol and even the MoonBit style loop syntax become useful.
  3. The current for x into y syntax is valid for index-based access, but the JS' for-of doesn't. To combine the benefits of both style, generator (for sequencing) support will be needed. Zig's for loop design is a good example.
  4. Are for statements enough? To maintain a robust type-based approach, it would be better to design them based on expressions.

@cometkim
Copy link
Member

@cometkim still got some design notes from the retreat?

https://github.com/JonoPrest/iterator-rescript/blob/retreat-note/RETREAT_NOTE.md

On the last retreat, we only discussed iterator semantics and simulating break/continue; we also need to deal with the early-return or jump (for escaping nested loops) semantics.

@cristianoc
Copy link
Collaborator

Early return keeps on coming up as a topic.
Perhaps it makes sense to explore that as a prerequisite to this.

@cknitt
Copy link
Member Author

cknitt commented Sep 19, 2025

For me, the for..of feature as implemented here would already be useful in and of itself because it

  1. allows the usage of await like in this example from the tests which would not be possible using arr->Array.forEach(...)
let asyncProcess = async () => {
  let results = []
  for item of arr {
    let result = await processData(item)
    results->Array.push(result)
  }
  results
}
  1. is more concise
for item for arr {
# vs.
arr->Array.forEach(item =>
  1. is more performant

  2. Increases our coverage of JS features that JS developer may expect to have

I agree that early return would be nice to have, but not sure if we should tie this to for..of.

I also agree that it would be a good idea to look into how iterators should work.
OTOH having this for arrays would be a low-hanging fruit that could hopefully be extended to iterators later.

@cometkim
Copy link
Member

OTOH having this for arrays would be a low-hanging fruit that could hopefully be extended to iterators later.

This is already a dangerous assumption. for-of loops are all about iterators, not arrays.

It should be designed to interact with iterator types. When it works with array types, it leads users to copy arbitrary iterators into arrays unnecessarily.

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.

4 participants