Skip to content
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

Normative Conventions: pretend primitives aren't iterable #152

Merged
merged 6 commits into from
Aug 7, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions normative-conventions.md
Original file line number Diff line number Diff line change
@@ -37,3 +37,11 @@ For the purposes of this guideline `-0` is considered to be an integral number (
Some APIs intentionally round non-integral inputs, for example as an attempt to provide a best-effort behavior, rather than because the API fundamentally only makes sense with integers. This guideline does not apply to those cases.

NB: This convention is new as of 2024, and most earlier parts of the language do not follow it.

## Reject primitives in iterable-taking positions

Any time an iterable or async-iterable value (a value that has a `Symbol.iterator` or `Symbol.asyncIterator` method) is expected, primitives should be treated as if they were not iterable. Usually, this will mean throwing a `TypeError`. If the user provides a primitive wrapper Object such as a String Object, however, it should be treated like any other Object.

Although primitive Strings are default iterable (`String.prototype` has a `Symbol.iterator` method which enumerates code points), it is now considered a mistake to iterate a String without specifying whether the String is providing an abstraction over code units, code points, grapheme clusters, or something else.

NB: This convention is new as of 2024, and most earlier parts of the language do not follow it. In particular, positional destructuring (both binding and assignment), array spread, argument spread, for-of loops, `yield *`, the `Set` and `AggregateError` constructors, `Object.groupBy`, `Map.groupBy`, `Promise.all`, `Promise.allSettled`, `Promise.any`, `Promise.race`, `Array.from`, the static `from` methods on typed array constructors, and `Iterator.from` (Stage 3 at time of writing) all accept primitives where iterables are expected.
Loading