This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.
The spec doesn't provide enough guidance as to when it's ok to use an array or when it's not ok (and when a sequence should be used instead... and vice versa). Seems I'm not the only one confused by this: http://darobin.github.io/api-design-cookbook/#sequences-and-arrays
http://wiki.whatwg.org/wiki/IDL We should kill [] I think. For attributes we could return a frozen array and replace the array with another frozen array if it needs to be updated. What other patterns do we have?
I think that [] was going to be able to replace all usages of *List or *Collection that are preexisting in the DOM (e.g., NodeList, HTMLCollection). Are you saying that it's better to just have specific interfaces that describe their specific behavior, than introduce a generic [] array-type that can handle all these scenarios? My guidance to internal teams at Microsoft has always centered around when to return unique instances per call (use sequence) or singleton objects with mutating array contents (use [] or *List/*Collection, etc.).
We should have something generic syntax-wise, but it should work around (frozen) JavaScript Array objects and not a new kind of IDL object (which is what [] is).
[] as currently specified can't replace NodeList and HTMLCollection because those have methods other than [] and .length that are used in the wild... Further, there seems to be a trend away from "live" lists (whether good or not). For a non-live list, a JS Array (if a new copy) or frozen JS Array (if shared with other consumers) seems just fine.
(In reply to comment #4) > [] as currently specified can't replace NodeList and HTMLCollection because > those have methods other than [] and .length that are used in the wild... And live lists seem to tend to sprout new methods anyway, even if they initially have only [] and .length. I'm down with killing type[] in favor of just using [ArrayClass] interfaces. > For a non-live list, a JS Array (if a new copy) or frozen JS Array (if > shared with other consumers) seems just fine. Is the frozen-ness something that needs to be indicated in prose?
> Is the frozen-ness something that needs to be indicated in prose? I would vastly prefer we do it in IDL...
One thing to watch out for is to avoid situations where `myDOMThing.arrayProp !== myDOMThing.arrayProp`. This would occur if you specify properties as having getters that always return fresh arrays (or that return new, frozen arrays that represent mutable underlying data). If you need a non-mutable view into data that could change over time, a method returning a (non-frozen, snapshot) array seems best to me.
(In reply to comment #5) > I'm down with killing type[] in favor of just using [ArrayClass] interfaces. The point would be to *not* introduce any interfaces at all. Whatever we'd use in the WebIDL, it would map to normal real JS Arrays.
Domenic, I'm not sure what you mean by "non-frozen, snapshot". Fundamentally, there are several kinds of APIs: 1) API that just returns a new array each time. These should return a sequence (which means just a normal writable JS Array) and should be methods, not property getters. 2) API that keeps returning the same array object as long as its contents do not change. This can be a method, of course (returning a frozen JS Array, say, so that one caller can't mess up what other callers see). Can it be a property getter? It seems like this is an OK thing to do, actually, since the new object would only appear when the list being represented has in fact changed. 3) APIs that return some sort of live arraylike collection. The problem here is that in most cases the liveness means that the DOM implementation needs to be able to write into the array but callers need to not be able to do so. What that means is that the script-visible behavior is basically some sort of proxy around an Array. As I said in comment 4, there has been a general movement away from case 3 in API design. Case 1 is non-controversial. So the main interesting thing is case 2.
(In reply to comment #9) > Domenic, I'm not sure what you mean by "non-frozen, snapshot". "Non-frozen" = normal writable JS array; "snapshot" = does not track the underlying mutable state, but instead gives you the elements that were available when you called the method. Basically I was talking about exactly your case 1. > 2) API that keeps returning the same array object as long as its contents do not change. This can be a method, of course (returning a frozen JS Array, say, so that one caller can't mess up what other callers see). Can it be a property getter? It seems like this is an OK thing to do, actually, since the new object would only appear when the list being represented has in fact changed. I think you're right; property getters are OK, at least if the returned array is frozen. It would be quite easy to implement such a property in JS using a getter that regenerates and caches an array if it detects a change in the underlying data. Put another way, this might be a natural pattern for ES5 developers who want to expose read-only views of mutable data to the outside world. A method feels a bit more preferable, but probably just because I'm used to working with so much ES3 code. Specific use cases might be helpful in deciding whether we want to recommend methods or properties. > 3) APIs that return some sort of live arraylike collection. The problem here is that in most cases the liveness means that the DOM implementation needs to be able to write into the array but callers need to not be able to do so. What that means is that the script-visible behavior is basically some sort of proxy around an Array. After a brief chat with darobin in IRC, I am no longer convinced this is a bad pattern, if done correctly. The difference between an array that does this (via proxies) and an object that does this (via getters) seems insubstantial. But, the correct way to do this needs some noodling before we even consider recommending it; the current patterns in the platform are scary. I'll try to make some time to draw up a readonly-array direct proxy that feels intuitive enough that we could consider using it. It might not be possible.
> I am no longer convinced this is a bad pattern, if done correctly. For what it's worth, the usual arguments I've heard against live lists fall into two categories: 1) They're hard to iterate over: you have to make sure that nothing modifies the list as a side-effect while you're iterating. Here's a common pitfall people fall into, for example: var kids = myNode.childNodes; for (var i = 0; i < kids.length; ++kids) { myNode.removeChild(kids[i]); } 2) They impose a performance burden on implementations that have to update the list whenever the set of things it reflects changes. This is maybe counterbalanced by the fact that live lists can sometimes do less work than non-live ones (e.g. getElementsByTagName("foo")[0] doesn't have to walk the whole DOM, just until it finds the first <foo>).
Since array[]s were removed, I guess we've provided all the necessary guidance ^_^