tc39 / proposal-iterator.range

A proposal for ECMAScript to add a built-in Iterator.range()
https://tc39.es/proposal-iterator.range/
MIT License
487 stars 13 forks source link

Consider framing this as a global object. #10

Closed pfgallagher closed 5 years ago

pfgallagher commented 5 years ago

I'm very happy to see this proposal exists and fully support it. Good thing I checked first, otherwise I probably would have ended up writing one myself! When I need a range, I usually use a basic snippet like this (which, of course, doesn't handle options like step size):

const range = (min, max) => Array((max - min) + 1).fill().map((el, idx) => idx + min);

I understand your rationale for implementing it on the number prototype Number object. That said, I do think putting it on the array prototype Array object might make more sense from a UX perspective. It looks like this may have been previously discussed, but perhaps a better solution would be to frame it as an extension of JavaScript's global objects. Since a range function would have such wide applicability, particularly in how it could transform iteration, I don't think it should be explicitly tied down in a specific prototype. Of course, it would also make it easier to use.

Just my two cents! Please let me know if there's anything I can do to help with the proposal. Thanks!

Jack-Works commented 5 years ago

Currently range exists on Number.range and BigInt.range. By putting it on the Array object, any example?

Array.range(0, 20) // generates a 0 to 20 Array?

But this proposal does not return an Array, it returns an Iterator to support range(0, Infinity).

temp1 = Number.range(0, 20) // range {<suspended>}
temp1.next() // {value: 0, done: false}
Array.from(temp1) // (19) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

If you want to use it as an array, do Array.from(Number.range(0, 20)) or [...Number.range(0, 20)]

pfgallagher commented 5 years ago

Thanks for the explanation! Custom iterators are still a bit new to me, but I experimented with the polyfill and I see what you mean. Very powerful stuff.

Basically what I meant is: because the range function is premised upon iteration rather than number manipulation (or array manipulation, for that matter), perhaps it should just be a global range instead of Number.range, e.g.:


for (const i of range(0, 20)) {
    console.log(i); // -> 0, 1, 2, ..., 19
};

console.log([...range(0, 20)]); // -> [0, 1, 2, ..., 19]
Jack-Works commented 5 years ago

Thanks for the explanation! Custom iterators are still a bit new to me, but I experimented with the polyfill and I see what you mean. Very powerful stuff.

Basically what I meant is: because the range function is premised upon iteration rather than number manipulation (or array manipulation, for that matter), perhaps it should just be a global range instead of Number.range, e.g.:

for (const i of range(0, 20)) {
  console.log(i); // -> 0, 1, 2, ..., 19
};

console.log([...range(0, 20)]); // -> [0, 1, 2, ..., 19]

Yes, that's a better interface for daily usage. But Javascript already puts too many stuff in the globalThis.

There is parseFloat defined in the ECMAScript 1st edition, but ES2015 still adds Math.parseFloat. So we can see there is a trend to put things into scopes (like Math.*) not global.

pfgallagher commented 5 years ago

I totally get your argument; I just think it should be a consideration.

obedm503 commented 5 years ago

Attaching it to Number and BigInt is more consistent with js. I'm also more used to python's global range, but I think another global doesn't really fit in.

There's also the point that a single global range would have to handle the differences between numbers and bigints. While not the strongest argument, having 2 separate ranges simplifies working with possible edge cases that arise from the differences between numbers and bigints.