Is your feature request related to a problem? Please describe.
New APIs need a proposal issue and maintainer sign-off before implementation, as requested in the review of PR #7229 (@bartlomieju, @tomas-zijdemans). This is that proposal.
Five APIs are missing from the std library and have no std equivalent today:
- @std/collections lacks a range() function. It's absent from std and hard to write correctly — a naive i += step accumulation compounds float error (range(0, 1, { step: 0.1 }) returns 11 elements ending in 0.9999999999999999).
- @std/collections lacks a countBy() helper; the natural workaround is composing Object.groupBy + .length.
- @std/text lacks string predicates isAlpha, isAlphanumeric, and isNumeric. The review flagged that the current ASCII-only drafts are a trap under Unicode-sounding names (isAlpha("café") → false, isNumeric("١٢٣") → false), especially since the package's own internals already use \p{L} (see text/_util.ts).
Describe the solution you'd like
Both target packages are stable (@std/collections 1.3.0, @std/text 1.0.19), so all APIs land as unstable_.ts files with an @experimental JSDoc tag, not re-exported from mod.ts, following the collections/unstable_cycle.ts / text/unstable_slugify.ts exemplars.
- @std/collections/unstable_range — range(startOrEnd, end?, options?): number[]
Numbers from start (default 0) up to but not including end, with optional { step }, including a one-arg overload (range(5) → [0, 1, 2, 3, 4]). Elements are computed from the index (start + i * stepValue, count = Math.max(0, Math.ceil((stop - start) / stepValue))) to avoid float accumulation, and stepValue is validated as finite.
- Open question: should range(5, 0) auto-descend (default step to -1), or require an explicit { step: -1 }? The auto-descend behavior is currently undocumented and untested.
- @std/collections/unstable_countBy — countBy<T, K>(array, keyFn): Record<K, number>
Counts occurrences of each key from keyFn into a Record<K, number>, accumulated in a Map and returned via Object.fromEntries (this also fixes a review-found bug where a "proto" key silently lost its count by hitting the object prototype setter).
- Open question: is this worth adding over composing Object.groupBy + .length? My argument is that it returns counts directly in a single well-scoped call, with stable semantics and no Map-ordering dependency.
- @std/text predicates — isAlpha, isAlphanumeric, isNumeric
- Open decision: ASCII-only (renamed to say so, e.g. isAsciiAlpha) vs Unicode-aware (/^\p{L}+$/u, /^\p{Nd}+$/u). My lean is Unicode-aware to match the existing \p{L} precedent, but this semantics can't change after 1.0, so a maintainer call is needed.
On sign-off, implementation is split into two PRs (one per package) so each releases as its own patch, per the review's suggestion.
Describe alternatives you've considered
- range: hand-rolled loops or Array.from({ length }, (_, i) => ...) — both re-implement the off-by-one and float-accuracy details this API centralizes.
- countBy: Object.groupBy(array, keyFn) then mapping groups to lengths — viable, which is exactly why the review asked for a case for countBy itself.
- Text predicates: keep ASCII-only with explicit names/documentation instead of Unicode semantics — listed as an option in the open decision.
Is your feature request related to a problem? Please describe.
New APIs need a proposal issue and maintainer sign-off before implementation, as requested in the review of PR #7229 (@bartlomieju, @tomas-zijdemans). This is that proposal.
Five APIs are missing from the std library and have no std equivalent today:
Describe the solution you'd like
Both target packages are stable (@std/collections 1.3.0, @std/text 1.0.19), so all APIs land as unstable_.ts files with an @experimental JSDoc tag, not re-exported from mod.ts, following the collections/unstable_cycle.ts / text/unstable_slugify.ts exemplars.
Numbers from start (default 0) up to but not including end, with optional { step }, including a one-arg overload (range(5) → [0, 1, 2, 3, 4]). Elements are computed from the index (start + i * stepValue, count = Math.max(0, Math.ceil((stop - start) / stepValue))) to avoid float accumulation, and stepValue is validated as finite.
Counts occurrences of each key from keyFn into a Record<K, number>, accumulated in a Map and returned via Object.fromEntries (this also fixes a review-found bug where a "proto" key silently lost its count by hitting the object prototype setter).
On sign-off, implementation is split into two PRs (one per package) so each releases as its own patch, per the review's suggestion.
Describe alternatives you've considered