Skip to content

[Proposal] Add Iterator.forEach and AsyncIterator.forEach #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
zth opened this issue Feb 16, 2023 · 0 comments · Fixed by #175
Closed

[Proposal] Add Iterator.forEach and AsyncIterator.forEach #38

zth opened this issue Feb 16, 2023 · 0 comments · Fixed by #175
Labels
proposal Proposals for changes to Core.

Comments

@zth
Copy link
Collaborator

zth commented Feb 16, 2023

The idiomatic way of iterating through all entries of an (async) iterator in JS is to use the for const of syntax:

// For regular iterators
for (const item of iterator) {
  console.log(item)
}

// For async iterators
for await (const item of iterator) {
  console.log(item)
}

However, this isn't possible in ReScript because we have no for const of syntax. So, I propose we add 2 helpers that accomplishes the same thing as for const of does, namely iterating through all items from the iterator.

They'd look like this:

// Regular iterator
// forEach: (Iterator.t<'a>, option<'a> => unit) => unit
someIterator->Iterator.forEach(value => {
  Console.log(value) // `option<'a>`
})

// Async iterator. Returns a promise since it's async
// forEach: (Iterator.t<'a>, option<'a> => unit) => promise<unit>
let processAsyncIterator = async () => {
 await someAsyncIterator->AsyncIterator.forEach(value => {
    Console.log(value) // `option<'a>`
  })
}

The implementation would be via a while loop:

// Regular
let forEach = (iterator, f) => {
  let iteratorDone = ref(false)

  while !iteratorDone.contents {
    let {done, value} = iterator->Iterator.next
    f(value)
    iteratorDone := done
  }
}

// Async
let forEach = async (iterator, f) => {
  let iteratorDone = ref(false)

  while !iteratorDone.contents {
    let {done, value} = await iterator->AsyncIterator.next
    f(value)
    iteratorDone := done
  }
}

I think this fits in Core because we'll never have the for const of syntax in ReScript, and this would help make it easy for beginners to use iterators whenever they encounter them.

@zth zth added the proposal Proposals for changes to Core. label Feb 27, 2023
@zth zth closed this as completed in #175 Feb 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal Proposals for changes to Core.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant