New Proposal: Number.range (Yes, range again)

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

New Proposal: Number.range (Yes, range again)

Jack Works
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++
    }
}
```


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: New Proposal: Number.range (Yes, range again)

Tab Atkins Jr.
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(end-start))
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
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: New Proposal: Number.range (Yes, range again)

Jacob Pratt
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.

Jacob Pratt

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(end-start))
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
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: New Proposal: Number.range (Yes, range again)

Jack Works
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? 

On Thu, Nov 29, 2018, 12:18 Jacob Pratt <[hidden email]> wrote:
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.

Jacob Pratt

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(end-start))
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
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: New Proposal: Number.range (Yes, range again)

Jacob Pratt
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 on-topic 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

On Thu, Nov 29, 2018 at 4:29 AM Jack Works <[hidden email]> wrote:
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? 

On Thu, Nov 29, 2018, 12:18 Jacob Pratt <[hidden email]> wrote:
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.

Jacob Pratt

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(end-start))
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
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: New Proposal: Number.range (Yes, range again)

Jordan Harband
It's not a "standard library" unless every part of it has gone through a full standards process.

On Wed, Nov 28, 2018 at 8:31 PM Jacob Pratt <[hidden email]> wrote:
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 on-topic 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

On Thu, Nov 29, 2018 at 4:29 AM Jack Works <[hidden email]> wrote:
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? 

On Thu, Nov 29, 2018, 12:18 Jacob Pratt <[hidden email]> wrote:
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.

Jacob Pratt

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(end-start))
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
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: New Proposal: Number.range (Yes, range again)

Cyril Auburtin
cf https://github.com/tc39/proposal-slice-notation/issues/19 which would be more powerful as a literal

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.

On Wed, Nov 28, 2018 at 8:31 PM Jacob Pratt <[hidden email]> wrote:
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 on-topic 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

On Thu, Nov 29, 2018 at 4:29 AM Jack Works <[hidden email]> wrote:
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? 

On Thu, Nov 29, 2018, 12:18 Jacob Pratt <[hidden email]> wrote:
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.

Jacob Pratt

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(end-start))
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
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: New Proposal: Number.range (Yes, range again)

Jack Works
In reply to this post by Jordan Harband
Hello everyone, I made a formal proposal https://github.com/Jack-Works/proposal-Number.range , welcome to disscuss the details in the repo!

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.

On Wed, Nov 28, 2018 at 8:31 PM Jacob Pratt <[hidden email]> wrote:
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 on-topic 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

On Thu, Nov 29, 2018 at 4:29 AM Jack Works <[hidden email]> wrote:
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? 

On Thu, Nov 29, 2018, 12:18 Jacob Pratt <[hidden email]> wrote:
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.

Jacob Pratt

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(end-start))
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
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: New Proposal: Number.range (Yes, range again)

Cyril Auburtin
I'm really cheering for the slice-notation range extension proposed in https://github.com/tc39/proposal-slice-notation/issues/19#issuecomment-421453934

```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 Fri, Jan 18, 2019 at 3:41 PM Jack Works <[hidden email]> wrote:
Hello everyone, I made a formal proposal https://github.com/Jack-Works/proposal-Number.range , welcome to disscuss the details in the repo!

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.

On Wed, Nov 28, 2018 at 8:31 PM Jacob Pratt <[hidden email]> wrote:
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 on-topic 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

On Thu, Nov 29, 2018 at 4:29 AM Jack Works <[hidden email]> wrote:
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? 

On Thu, Nov 29, 2018, 12:18 Jacob Pratt <[hidden email]> wrote:
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.

Jacob Pratt

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(end-start))
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
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss