-
Notifications
You must be signed in to change notification settings - Fork 9
Returns array instead of iterator #23
Comments
Arrays seem like they're much nicer to work with, that's for sure. |
I'm hesitant to spec an API that involves allocating an array of hundreds or thousands of elements. |
Only a couple of hundreds. 😄
There are two angles here:
Do you have concerns for both issues or only one of them? |
A bit of both. I expect the common use case for these strings to involve a for loop iterating over them. It's well established software engineering best practice that iterators should not need to allocate extra memory. |
If you’re iterating over all of them, you’ll almost always have to reify them into an array - especially prior to iterator helpers landing - so the memory cost would be smaller as an array than as an iterator + array, no? |
Not if you are:
What are the use cases where you would actually want these in an array? |
When i want to use filter, map, etc (absent iterator helpers). Also in general i prefer dealing with arrays of things in programming rather than having to do imperative loops all over the place. |
If you really want an array, you can use the spread operator What I don't think we should do is force people to get an array from these functions if they don't need one. It seems like bad API design for new APIs. Python, Java, Rust, C++, and many other languages have moved from arrays to iterators a long time ago. |
Currently in Intl API all the formatToParts return array, especially for example- Intl.ListFormat.prototype.formatToParts. If the input is a list of 500 items the return value will be an array of >500 items. so it is NOT the first method Intl API return array, right? How come when we added formatToParts we decided to return array instead of iterator if that will be an issue, especially for Intl.ListFormat.prototype.formatToParts which take an iterator as input... |
formatToParts is fundamentally different. It's the same as the string returned by .format but with additional annotations, computed on the fly and returned to the client. I see this also in the same category as the regex groups function. Here, the data is deterministic. Under the hood, we probably have a static array-like structure stored in C++. We want to give a way to access that static C++ array without having to copy the whole thing into JS every time someone calls the function. |
but your "I expect the common use case for these strings to involve a for loop iterating over them. It's well established software engineering best practice that iterators should not need to allocate extra memory." statement also apply to formatToParts, right? |
@sffc the alternative is forcing people to make an array if they don't need an iterator. For a relatively finitely-bounded set of values, I don't think either choice is inherently better or less inconvenient for some. |
No, my statement doesn't apply to formatToParts, because there is no way to avoid allocating memory. If we didn't give the array to JS, we'd still have to allocate it in C++. |
hum? Why is that? In v8, Intl.ListFormat.prototype.formatToParts is calling nextPosition() of icu::FormattedList in C++ to iterate through, so internally it is calling an iterator, If the API was designed to return iterator, it could surely remember the icu::FormattedList internal slot and allocate the memory of one call at a time. Say if the input is an iterator of 1000 item and the formatTo parts has 2003 parts, the next of JS will be called 2003 times and each time it call the nextPosition() and allocate memory for that, right? |
In 2021-06-03 ECMA402 TG2 we spend a lot of time discuss this. No agreement reach. I will put down each persons's opinion later. I will also change the spec in a way to have both approach available and label and back to ECMA402 again later to let people take a look before the July meeting. |
What people paste into the chat channel about this issue Louis-Aimé de Fouquières12:30Equal to me. Jeff Walden12:31Yeah -- JS writers are going to assume an array here, most likely. And JS doesn't have the same high-quality standalone iteration helpers like Python/Rust/etc. have, to make working with iterators easy. Leo Balter12:31for the records, I'm ok either way as well Yusuke Suzuki12:31I'm ok for Array too. Richard Gibson12:31I'm also ok either way, but share Jordan's dispreference for introducing new iterator prototypes Leo Balter12:34Not any strong preference, but Arrays seems more intuitive for Developers Experience. In cases like this, I'd consult with JS Educators. |
Here is what I will do. I will put in both the specification for Iterator and Array into the proposal and mark them so next time we can take a look at two different version of spec text to vote for. |
I now change it to array. |
Split from #22
13. CreateSupportedValuesIterator ( list )
%SupportedValuesIterator%
object, otherwise there's nonext
method to iterate over the elements.? Yield(E)
should be changed to! Yield(E)
given that there's no way to resume this generator with an abrupt completion. (I have no idea why ECMA-262 always uses fallible? Yield()
for all its iterators, even when the operation is infallible.)I have some doubts about returning iterators instead of for example arrays, because:
var array = [...Intl.supportedValuesOf(key)]
to get something useful to operate upon, we may have made a design mistake.Intl.DisplayNames
and time zones can be translated viaIntl.DateTimeFormat
(and the "Extend TimeZoneName Option" proposal will even provide better localisations!), but neither calendars, nor collations, nor numbering systems, nor units can be localised right now. Let's say an application wants to provide a date control with a customisable calendar, just providing the BCP47 names to an end user won't be super useful. (Later: I totally forgot about the "Intl.DisplayNames v2" proposal, so "unit" is a better example for missing localisation atm.)The text was updated successfully, but these errors were encountered: