

Hello everyone. I've searched for the mailing list, there are some discussions add `new Range` or `a ... b` into the language but not become a formal proposal.
I've made a full demo(polyfill) these days. Anyone interested?
Preview: `for (let i of Number.range(1, 5)) console.log(i)`
And there is an extended version that let range support number range check `if ( x in Number.range(0, 100) )`. About usage, test case, and demo of the extended version is posted on gist.
( This proposal can also/or add an new operator instead. `Number.range(x, y)` => `x...y` `Number.range(x, y, z)` => `(x...y).step(z)` or `x...z>y` or something else, and other behavior keep same with the Number.range implmentation in the gist )
Here is the base version of the proposal ```js Number.range = function*(from, to, step) { if ( typeof from !== 'number' && typeof from !== 'bigint' && (typeof to !== 'number' && typeof to !== 'bigint') && (typeof step !== 'number' && typeof step !== 'bigint' && typeof step !== 'undefined') ) throw new TypeError('All parameters must be a number or a BigInt')
if (typeof from === 'bigint' && typeof step === 'undefined') step = 1n else if (typeof from === 'number' && typeof step === 'undefined') step = 1
if (typeof from !== typeof to  typeof from !== typeof step) throw new TypeError('Type of all parameters must be the same') if (typeof from === "number" && Number.isNaN(from)  Number.isNaN(to)  Number.isNaN(step)) return; // Quit early with no value yield
// Math.abs does not support BigInt. const abs = x => (x >= (typeof x === 'bigint' ? 0n : 0) ? x : x)
const increase = to > from // Ignore the symbol if (increase) step = abs(step) else step = abs(step)
let count = typeof from === 'bigint' ? 1n : 1 let now = from while (increase ? !(now >= to) : !(to >= now)) { yield now now = from + step * count count++ } } ```
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss


I end up writing a range function in virtually every project I use, so
yeah, I think this is worthwhile.
My own preferences, based on Python precedence:
Number.range(end) === Number.range(0, end, 1)
Number.range(start, end) === Number.range(start, end, Math.sign(endstart))
Number.range(start, end, step) => {
if start < end && step > 0: yield all (start + k*step), for k from 0
to infinity, less than end
elif start > end && step < 0: yield all (start + k*step), for k from
0 to infinity, greater than end
else: yield nothing
}
So:
* [...Number.range(5)] evaluates to [0, 1, 2, 3, 4]
* [...Number.range(0)] evaluates to []
* [...Number.range(5)] evaluates to []
* [...Number.range(1, 3)] evaluates to [1, 0, 1, 2]
* [...Number.range(3, 1)] evaluates to [3, 2, 1, 0]
* [...Number.range(1, 1)] evaluates to []
* [...Number.range(0, 10, 5)] evaluates to [0, 5]
* [...Number.range(0, 10, 5)] evaluates to []
~TJ
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss


Quick, simple TypeScript range function (with overloads, of course).
``` export function range(end: number): IterableIterator<number>; export function range(start: number, end: number): IterableIterator<number>; export function range(start: number, end: number, step: number): IterableIterator<number>; export function* range(start: number, end?: number, step?: number): IterableIterator<number> { // overload #1 if (end === undefined) { [start, end, step] = [0, start, 1]; }
// overload #2 if (step === undefined) { step = Math.sign(end  start); }
// ensure we have the appropriate types if (typeof start !== 'number'  typeof end !== 'number'  typeof step !== 'number') { throw new TypeError('all parameters must be of type number'); }
while ((start < end && step > 0)  (start > end && step < 0)) { yield start; start += step; } }
```
IMO, we should focus on building up a JavaScript standard library that has tons of useful utilities like this, rather than continue to add methods onto namespaces. Perhaps that's just me, though.
On Wed, Nov 28, 2018 at 9:33 PM Tab Atkins Jr. < [hidden email]> wrote: I end up writing a range function in virtually every project I use, so
yeah, I think this is worthwhile.
My own preferences, based on Python precedence:
Number.range(end) === Number.range(0, end, 1)
Number.range(start, end) === Number.range(start, end, Math.sign(endstart))
Number.range(start, end, step) => {
if start < end && step > 0: yield all (start + k*step), for k from 0
to infinity, less than end
elif start > end && step < 0: yield all (start + k*step), for k from
0 to infinity, greater than end
else: yield nothing
}
So:
* [...Number.range(5)] evaluates to [0, 1, 2, 3, 4]
* [...Number.range(0)] evaluates to []
* [...Number.range(5)] evaluates to []
* [...Number.range(1, 3)] evaluates to [1, 0, 1, 2]
* [...Number.range(3, 1)] evaluates to [3, 2, 1, 0]
* [...Number.range(1, 1)] evaluates to []
* [...Number.range(0, 10, 5)] evaluates to [0, 5]
* [...Number.range(0, 10, 5)] evaluates to []
~TJ
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss


Oh, I'm not here to find out how to implement a range in detail. That's the trivial things, I want to first make it become a stage 0 proposal, then we can discuss if we need some overload or how to deal with the edge cases. Ps, does Pratt mean we should add it as a standard library in the stage 1 standard libraray proposal? Quick, simple TypeScript range function (with overloads, of course).
``` export function range(end: number): IterableIterator<number>; export function range(start: number, end: number): IterableIterator<number>; export function range(start: number, end: number, step: number): IterableIterator<number>; export function* range(start: number, end?: number, step?: number): IterableIterator<number> { // overload #1 if (end === undefined) { [start, end, step] = [0, start, 1]; }
// overload #2 if (step === undefined) { step = Math.sign(end  start); }
// ensure we have the appropriate types if (typeof start !== 'number'  typeof end !== 'number'  typeof step !== 'number') { throw new TypeError('all parameters must be of type number'); }
while ((start < end && step > 0)  (start > end && step < 0)) { yield start; start += step; } }
```
IMO, we should focus on building up a JavaScript standard library that has tons of useful utilities like this, rather than continue to add methods onto namespaces. Perhaps that's just me, though.
On Wed, Nov 28, 2018 at 9:33 PM Tab Atkins Jr. < [hidden email]> wrote: I end up writing a range function in virtually every project I use, so
yeah, I think this is worthwhile.
My own preferences, based on Python precedence:
Number.range(end) === Number.range(0, end, 1)
Number.range(start, end) === Number.range(start, end, Math.sign(endstart))
Number.range(start, end, step) => {
if start < end && step > 0: yield all (start + k*step), for k from 0
to infinity, less than end
elif start > end && step < 0: yield all (start + k*step), for k from
0 to infinity, greater than end
else: yield nothing
}
So:
* [...Number.range(5)] evaluates to [0, 1, 2, 3, 4]
* [...Number.range(0)] evaluates to []
* [...Number.range(5)] evaluates to []
* [...Number.range(1, 3)] evaluates to [1, 0, 1, 2]
* [...Number.range(3, 1)] evaluates to [3, 2, 1, 0]
* [...Number.range(1, 1)] evaluates to []
* [...Number.range(0, 10, 5)] evaluates to [0, 5]
* [...Number.range(0, 10, 5)] evaluates to []
~TJ
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss


I'm not saying we should add it on to that proposal, but rather saying that I think more effort should be put into a standard library where things like this don't need to go through a full standards process. That's just my opinion, and borderline ontopic for this specific suggestion.
I'm absolutely in favor of having a `range` method, it's just _where_ it should be that I differ.
Jacob Pratt Oh, I'm not here to find out how to implement a range in detail. That's the trivial things, I want to first make it become a stage 0 proposal, then we can discuss if we need some overload or how to deal with the edge cases.Ps, does Pratt mean we should add it as a standard library in the stage 1 standard libraray proposal? Quick, simple TypeScript range function (with overloads, of course).
``` export function range(end: number): IterableIterator<number>; export function range(start: number, end: number): IterableIterator<number>; export function range(start: number, end: number, step: number): IterableIterator<number>; export function* range(start: number, end?: number, step?: number): IterableIterator<number> { // overload #1 if (end === undefined) { [start, end, step] = [0, start, 1]; }
// overload #2 if (step === undefined) { step = Math.sign(end  start); }
// ensure we have the appropriate types if (typeof start !== 'number'  typeof end !== 'number'  typeof step !== 'number') { throw new TypeError('all parameters must be of type number'); }
while ((start < end && step > 0)  (start > end && step < 0)) { yield start; start += step; } }
```
IMO, we should focus on building up a JavaScript standard library that has tons of useful utilities like this, rather than continue to add methods onto namespaces. Perhaps that's just me, though.
On Wed, Nov 28, 2018 at 9:33 PM Tab Atkins Jr. < [hidden email]> wrote: I end up writing a range function in virtually every project I use, so
yeah, I think this is worthwhile.
My own preferences, based on Python precedence:
Number.range(end) === Number.range(0, end, 1)
Number.range(start, end) === Number.range(start, end, Math.sign(endstart))
Number.range(start, end, step) => {
if start < end && step > 0: yield all (start + k*step), for k from 0
to infinity, less than end
elif start > end && step < 0: yield all (start + k*step), for k from
0 to infinity, greater than end
else: yield nothing
}
So:
* [...Number.range(5)] evaluates to [0, 1, 2, 3, 4]
* [...Number.range(0)] evaluates to []
* [...Number.range(5)] evaluates to []
* [...Number.range(1, 3)] evaluates to [1, 0, 1, 2]
* [...Number.range(3, 1)] evaluates to [3, 2, 1, 0]
* [...Number.range(1, 1)] evaluates to []
* [...Number.range(0, 10, 5)] evaluates to [0, 5]
* [...Number.range(0, 10, 5)] evaluates to []
~TJ
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss


It's not a "standard library" unless every part of it has gone through a full standards process. I'm not saying we should add it on to that proposal, but rather saying that I think more effort should be put into a standard library where things like this don't need to go through a full standards process. That's just my opinion, and borderline ontopic for this specific suggestion.
I'm absolutely in favor of having a `range` method, it's just _where_ it should be that I differ.
Jacob Pratt
Oh, I'm not here to find out how to implement a range in detail. That's the trivial things, I want to first make it become a stage 0 proposal, then we can discuss if we need some overload or how to deal with the edge cases.Ps, does Pratt mean we should add it as a standard library in the stage 1 standard libraray proposal? Quick, simple TypeScript range function (with overloads, of course).
``` export function range(end: number): IterableIterator<number>; export function range(start: number, end: number): IterableIterator<number>; export function range(start: number, end: number, step: number): IterableIterator<number>; export function* range(start: number, end?: number, step?: number): IterableIterator<number> { // overload #1 if (end === undefined) { [start, end, step] = [0, start, 1]; }
// overload #2 if (step === undefined) { step = Math.sign(end  start); }
// ensure we have the appropriate types if (typeof start !== 'number'  typeof end !== 'number'  typeof step !== 'number') { throw new TypeError('all parameters must be of type number'); }
while ((start < end && step > 0)  (start > end && step < 0)) { yield start; start += step; } }
```
IMO, we should focus on building up a JavaScript standard library that has tons of useful utilities like this, rather than continue to add methods onto namespaces. Perhaps that's just me, though.
On Wed, Nov 28, 2018 at 9:33 PM Tab Atkins Jr. < [hidden email]> wrote: I end up writing a range function in virtually every project I use, so
yeah, I think this is worthwhile.
My own preferences, based on Python precedence:
Number.range(end) === Number.range(0, end, 1)
Number.range(start, end) === Number.range(start, end, Math.sign(endstart))
Number.range(start, end, step) => {
if start < end && step > 0: yield all (start + k*step), for k from 0
to infinity, less than end
elif start > end && step < 0: yield all (start + k*step), for k from
0 to infinity, greater than end
else: yield nothing
}
So:
* [...Number.range(5)] evaluates to [0, 1, 2, 3, 4]
* [...Number.range(0)] evaluates to []
* [...Number.range(5)] evaluates to []
* [...Number.range(1, 3)] evaluates to [1, 0, 1, 2]
* [...Number.range(3, 1)] evaluates to [3, 2, 1, 0]
* [...Number.range(1, 1)] evaluates to []
* [...Number.range(0, 10, 5)] evaluates to [0, 5]
* [...Number.range(0, 10, 5)] evaluates to []
~TJ
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss


On Thu, Nov 29, 2018 at 8:01 AM Jordan Harband < [hidden email]> wrote: It's not a "standard library" unless every part of it has gone through a full standards process.
I'm not saying we should add it on to that proposal, but rather saying that I think more effort should be put into a standard library where things like this don't need to go through a full standards process. That's just my opinion, and borderline ontopic for this specific suggestion.
I'm absolutely in favor of having a `range` method, it's just _where_ it should be that I differ.
Jacob Pratt
Oh, I'm not here to find out how to implement a range in detail. That's the trivial things, I want to first make it become a stage 0 proposal, then we can discuss if we need some overload or how to deal with the edge cases.Ps, does Pratt mean we should add it as a standard library in the stage 1 standard libraray proposal? Quick, simple TypeScript range function (with overloads, of course).
``` export function range(end: number): IterableIterator<number>; export function range(start: number, end: number): IterableIterator<number>; export function range(start: number, end: number, step: number): IterableIterator<number>; export function* range(start: number, end?: number, step?: number): IterableIterator<number> { // overload #1 if (end === undefined) { [start, end, step] = [0, start, 1]; }
// overload #2 if (step === undefined) { step = Math.sign(end  start); }
// ensure we have the appropriate types if (typeof start !== 'number'  typeof end !== 'number'  typeof step !== 'number') { throw new TypeError('all parameters must be of type number'); }
while ((start < end && step > 0)  (start > end && step < 0)) { yield start; start += step; } }
```
IMO, we should focus on building up a JavaScript standard library that has tons of useful utilities like this, rather than continue to add methods onto namespaces. Perhaps that's just me, though.
On Wed, Nov 28, 2018 at 9:33 PM Tab Atkins Jr. < [hidden email]> wrote: I end up writing a range function in virtually every project I use, so
yeah, I think this is worthwhile.
My own preferences, based on Python precedence:
Number.range(end) === Number.range(0, end, 1)
Number.range(start, end) === Number.range(start, end, Math.sign(endstart))
Number.range(start, end, step) => {
if start < end && step > 0: yield all (start + k*step), for k from 0
to infinity, less than end
elif start > end && step < 0: yield all (start + k*step), for k from
0 to infinity, greater than end
else: yield nothing
}
So:
* [...Number.range(5)] evaluates to [0, 1, 2, 3, 4]
* [...Number.range(0)] evaluates to []
* [...Number.range(5)] evaluates to []
* [...Number.range(1, 3)] evaluates to [1, 0, 1, 2]
* [...Number.range(3, 1)] evaluates to [3, 2, 1, 0]
* [...Number.range(1, 1)] evaluates to []
* [...Number.range(0, 10, 5)] evaluates to [0, 5]
* [...Number.range(0, 10, 5)] evaluates to []
~TJ
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss


On Thu, Nov 29, 2018 at 3:01 PM Jordan Harband < [hidden email]> wrote: It's not a "standard library" unless every part of it has gone through a full standards process.
I'm not saying we should add it on to that proposal, but rather saying that I think more effort should be put into a standard library where things like this don't need to go through a full standards process. That's just my opinion, and borderline ontopic for this specific suggestion.
I'm absolutely in favor of having a `range` method, it's just _where_ it should be that I differ.
Jacob Pratt
Oh, I'm not here to find out how to implement a range in detail. That's the trivial things, I want to first make it become a stage 0 proposal, then we can discuss if we need some overload or how to deal with the edge cases.Ps, does Pratt mean we should add it as a standard library in the stage 1 standard libraray proposal? Quick, simple TypeScript range function (with overloads, of course).
``` export function range(end: number): IterableIterator<number>; export function range(start: number, end: number): IterableIterator<number>; export function range(start: number, end: number, step: number): IterableIterator<number>; export function* range(start: number, end?: number, step?: number): IterableIterator<number> { // overload #1 if (end === undefined) { [start, end, step] = [0, start, 1]; }
// overload #2 if (step === undefined) { step = Math.sign(end  start); }
// ensure we have the appropriate types if (typeof start !== 'number'  typeof end !== 'number'  typeof step !== 'number') { throw new TypeError('all parameters must be of type number'); }
while ((start < end && step > 0)  (start > end && step < 0)) { yield start; start += step; } }
```
IMO, we should focus on building up a JavaScript standard library that has tons of useful utilities like this, rather than continue to add methods onto namespaces. Perhaps that's just me, though.
On Wed, Nov 28, 2018 at 9:33 PM Tab Atkins Jr. < [hidden email]> wrote: I end up writing a range function in virtually every project I use, so
yeah, I think this is worthwhile.
My own preferences, based on Python precedence:
Number.range(end) === Number.range(0, end, 1)
Number.range(start, end) === Number.range(start, end, Math.sign(endstart))
Number.range(start, end, step) => {
if start < end && step > 0: yield all (start + k*step), for k from 0
to infinity, less than end
elif start > end && step < 0: yield all (start + k*step), for k from
0 to infinity, greater than end
else: yield nothing
}
So:
* [...Number.range(5)] evaluates to [0, 1, 2, 3, 4]
* [...Number.range(0)] evaluates to []
* [...Number.range(5)] evaluates to []
* [...Number.range(1, 3)] evaluates to [1, 0, 1, 2]
* [...Number.range(3, 1)] evaluates to [3, 2, 1, 0]
* [...Number.range(1, 1)] evaluates to []
* [...Number.range(0, 10, 5)] evaluates to [0, 5]
* [...Number.range(0, 10, 5)] evaluates to []
~TJ
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss


```js for (const i of Number.range(0, 43)) { console.log(i) // 0 to 42 }
const fakeData = [...Number.range(1, 21)].map(x => x ** 2) ``` becomes ```js for (const i of (0:43)) { console.log(i) // 0 to 42 }
const fakeData = [...(1:21)].map(x => x ** 2) ```
On Thu, Nov 29, 2018 at 3:01 PM Jordan Harband < [hidden email]> wrote: It's not a "standard library" unless every part of it has gone through a full standards process.
I'm not saying we should add it on to that proposal, but rather saying that I think more effort should be put into a standard library where things like this don't need to go through a full standards process. That's just my opinion, and borderline ontopic for this specific suggestion.
I'm absolutely in favor of having a `range` method, it's just _where_ it should be that I differ.
Jacob Pratt
Oh, I'm not here to find out how to implement a range in detail. That's the trivial things, I want to first make it become a stage 0 proposal, then we can discuss if we need some overload or how to deal with the edge cases.Ps, does Pratt mean we should add it as a standard library in the stage 1 standard libraray proposal? Quick, simple TypeScript range function (with overloads, of course).
``` export function range(end: number): IterableIterator<number>; export function range(start: number, end: number): IterableIterator<number>; export function range(start: number, end: number, step: number): IterableIterator<number>; export function* range(start: number, end?: number, step?: number): IterableIterator<number> { // overload #1 if (end === undefined) { [start, end, step] = [0, start, 1]; }
// overload #2 if (step === undefined) { step = Math.sign(end  start); }
// ensure we have the appropriate types if (typeof start !== 'number'  typeof end !== 'number'  typeof step !== 'number') { throw new TypeError('all parameters must be of type number'); }
while ((start < end && step > 0)  (start > end && step < 0)) { yield start; start += step; } }
```
IMO, we should focus on building up a JavaScript standard library that has tons of useful utilities like this, rather than continue to add methods onto namespaces. Perhaps that's just me, though.
On Wed, Nov 28, 2018 at 9:33 PM Tab Atkins Jr. < [hidden email]> wrote: I end up writing a range function in virtually every project I use, so
yeah, I think this is worthwhile.
My own preferences, based on Python precedence:
Number.range(end) === Number.range(0, end, 1)
Number.range(start, end) === Number.range(start, end, Math.sign(endstart))
Number.range(start, end, step) => {
if start < end && step > 0: yield all (start + k*step), for k from 0
to infinity, less than end
elif start > end && step < 0: yield all (start + k*step), for k from
0 to infinity, greater than end
else: yield nothing
}
So:
* [...Number.range(5)] evaluates to [0, 1, 2, 3, 4]
* [...Number.range(0)] evaluates to []
* [...Number.range(5)] evaluates to []
* [...Number.range(1, 3)] evaluates to [1, 0, 1, 2]
* [...Number.range(3, 1)] evaluates to [3, 2, 1, 0]
* [...Number.range(1, 1)] evaluates to []
* [...Number.range(0, 10, 5)] evaluates to [0, 5]
* [...Number.range(0, 10, 5)] evaluates to []
~TJ
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss
_______________________________________________
esdiscuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/esdiscuss

