whatwg / webidl

Web IDL Standard
https://webidl.spec.whatwg.org/
Other
405 stars 162 forks source link

Can we use ObjectCreate in object creation? + other editorial tweaks #655

Open domenic opened 5 years ago

domenic commented 5 years ago

https://heycam.github.io/webidl/#internally-create-a-new-object-implementing-the-interface

I think we can use ObjectCreate() for steps 4-6. This would also allow us to move

Unless otherwise specified, the [[Extensible]] internal slot of objects defined in this section has the value true

into the algorithm.

We'd need to add something like "in realm" still, but I think that's nice; it shows how we're more explicit than ES in this one respect, but everything else is aligned with normal practices.

Best done after #654.


While in that area, I think there are a few sentences in the intro to https://heycam.github.io/webidl/#ecmascript-binding which are becoming redundant these days now that object creation is imperative:

Unless otherwise specified, exotic objects defined in this section and other specifications have the same internal slots as ordinary objects, and all of the internal methods for which alternative definitions are not given are the same as those of ordinary objects.

Unless otherwise specified, the [[Prototype]] internal slot of objects defined in this section is %ObjectPrototype%.

Ms2ger commented 5 years ago

I've avoided ObjectCreate() because it seems to deal explicitly with "ordinary" objects, and it's not clear to me that's what we want for the legacy getter/setter objects. Then again, I'm not sure if that's a problem.

domenic commented 5 years ago

You're right that in spirit it seems like ObjectCreate() is meant to only produce ordinary objects. We're creating our exotic objects by first creating an ordinary object, then overriding its internal methods. Hrm.

annevk commented 5 years ago

@domenic note that JavaScript itself also has the pattern of overriding internal methods: https://github.com/tc39/ecma262/pull/1437.

TimothyGu commented 5 years ago

See also #657. I happen to think that we should stay away from ObjectCreate, if only because ES doesn't do it with any of its exotic objects. For example, ArrayCreate doesn't use ObjectCreate but instead has something like

  1. Let A be a newly created Array exotic object.

even though arrays are basically plain ordinary objects, its [[DefineOwnProperty]] being the only difference.

In other words, I don't think exotic objects are created by "upgrading" or "subclassing" from ordinary objects. They are not in ES, nor implementations. If we were to do it the spec would probably be unambiguous still, but then we would be the only spec that does it.

annevk commented 5 years ago

It might be worth escalating to TC39 though to figure out if there's a meaningful difference that's intended to be conveyed, and if so, make that clearer somehow.

jmdyck commented 5 years ago

I think the reason that the ES spec says: Let _A_ be a newly created Array exotic object. rather than: Let _A_ be ObjectCreate(...). is that the latter form doesn't give you anything explicit that says "this is an Array exotic object", which you need, for example, when an algorithm step says: If _argument_ is an Array exotic object, ...

annevk commented 5 years ago

@jmdyck I see, it'd make more sense if exotic object was defined from first principles so you don't get that ambiguity.

allenwb commented 5 years ago

The intent was that new exotic objects or exotic objects defined in other specifications should follow the pattern established within 9.4. This includes specify a xxxCreate abstraction operation for each new kind of exotic object.

it'd make more sense if exotic object was defined from first principles so you don't get that ambiguity.

I'm not sure what ambiguity you mean. ObjectCreate, by definition, creates ordinary objects. Exotic objects are created some other way and in a manner that explicitly identifies the created object as exotic. That is what ArrayCreate does for Array exotic objects.

first principles

Which first principles do you have in mind. The only first principles that apply to exotic object are the concept of object identify and that they must expose (to the rest of the specification) the behavior of the essential internal methods that conform to the essential invariants. It is the job of exotic object creation abstract operations such as ArrayCreate to provide such a definition and that is what it does:

  1. Let A be a newly created Array exotic object.
  2. Set A's essential internal methods except for [[DefineOwnProperty]] to the default ordinary object definitions specified in 9.1.
  3. Set A.[[DefineOwnProperty]] as specified in 9.4.2.1.
  4. Set A.[[Prototype]] to proto.
  5. Set A.[[Extensible]] to true.

In particular, step 4 both creates a distinct object (ie with identity) and explicitly "brands" (for use in the spec) the new object as an Array exotic object. ObjectCreate creates and brands ordinary objects.

One thing that is missing (its implicit) from step 5 is the inclusion of the ordinary object internal slots in the newly created array exotic object. It would probably be better if it's step 5 (and other similar xxxCreate abstract operations) was restated something like:

  1. Incorporate into A the internal slots and set A's essential internal methods except for [[DefineOwnProperty]] to the default ordinary object definitions specified in 9.1.

Also object creation should be considered an atomic action so the ordering of steps 6-8 is not significance. You could imagine all of steps 5-8 being listed as bullet points under step 4.

Ms2ger commented 5 years ago

Note https://github.com/tc39/ecma262/pull/1460

annevk commented 4 years ago

https://github.com/tc39/ecma262/commit/e3707ac9e14b75b9513d6b09c394dee6473c5ddf landed so we'll need to change how we do object creation. While doing so it might also be worthwhile to see if we can do WindowProxy and Location in a better way.