Introduce the observable array type (proxy-based) by domenic · Pull Request #840 · whatwg/webidl (original) (raw)

There are some caveats in the specific comments, but in general, this seems doable. Actual implementation might be a bit of a pain in various ways, both in terms of hooking at a low level into attribute getters and setters, and in terms of introducing a totally new type of object. It's probably doable somewhat sanely, but I haven't thought through the details yet.

Presumably the interface the property is defined on would need to maintain a mirror of the list that it syncs using the delete/set hooks. From that point of view, the separate delete and set callbacks when one of the existing indexed properties changed are not ideal: it means either implementations have to diverge from the spec and do a fused delete+set or the mirrored list needs to support a temporary hole, or the mirrored list ends up doing extra shifting around of the list contents. Adding an optional "old value" to the set hook would address this, I think... though if a mirror is being maintained anyway, just the index is enough, right? I'm not 100% sure whether there are use cases for not maintaining a mirrored list.

I'm not sure how easy it would be to optimize this sort of thing in JITs, but maybe it's not a huge issue?

One question I do have, just in terms of which bits here are inherent to the proposal vs which are accidental. What would the observable behavior changes be, if any, if the proxy had two arrays backing it: one the proxy target and one for storing all the indexed props and length state (and possibly all props?). It'd require a lot more hooks (e.g. getOwnPropertyDescriptor), but assuming we implemented those?

Or put another way, is the proposal black-box-identical to having a proxy that returns true for IsArray via "magic" (only possible in ES spec terms if target is an array, but engines may have other ways of doing the magic), returns Array.prototype from getPrototypeOf, stores a list of IDL values, not an array of ES values, and defines all the proxy traps appropriately to work with that list of IDL values. Or, still black-box-identically, have an IDL object with an indexed getter and indexed setter, but returning true from IsArray and with Array.prototype on the proto chain.

I think that except for the cases when T is a dictionary or sequence type these are all black-box equivalent. If that's the case, then implementation and optimization is likely much simpler, at the cost of not obviously matching the spec... If they are not black-box-equivalent, it's worth understanding where they diverge.