New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4.2.1 states rules about constructors that Proxy doesn't obey #471

Closed
webbedspace opened this Issue Mar 12, 2016 · 12 comments

Comments

Projects
None yet
6 participants
@webbedspace

webbedspace commented Mar 12, 2016

https://tc39.github.io/ecma262/#sec-objects

  • Each constructor is a function that has a property named "prototype" - Proxy is a constructor but lacks this property.
  • Every object created by a constructor has an implicit reference (called the object's prototype) to the value of its constructor's "prototype" property. - exotic proxy objects do not.

This is just an informative section, but I think the "Each" and "Every" in those lines should be watered down.

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Mar 12, 2016

Member

Perhaps it would make more sense for Proxy to not require new if it doesn't have .prototype?

Member

ljharb commented Mar 12, 2016

Perhaps it would make more sense for Proxy to not require new if it doesn't have .prototype?

@domenic

This comment has been minimized.

Show comment
Hide comment
@domenic

domenic Mar 12, 2016

Member

@ljharb I agree, but there was a TC39 meeting where it was decided on requiring new, for vague reasons. It was before my time, but I remember reading the notes and being pretty dissatisfied with the reasoning.

Member

domenic commented Mar 12, 2016

@ljharb I agree, but there was a TC39 meeting where it was decided on requiring new, for vague reasons. It was before my time, but I remember reading the notes and being pretty dissatisfied with the reasoning.

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Mar 12, 2016

Member

Then on the flip side - perhaps Proxy should have a .prototype object, even if the resulting instance doesn't use it (which is totally doable in ES3 even)?

Member

ljharb commented Mar 12, 2016

Then on the flip side - perhaps Proxy should have a .prototype object, even if the resulting instance doesn't use it (which is totally doable in ES3 even)?

@allenwb

This comment has been minimized.

Show comment
Hide comment
@allenwb

allenwb Mar 12, 2016

Member

4.2 is summary of the language that dates to ES1 (thanks, rpg). As it states, 4.2 is a non-normative overview of the language. It's ok of it to fuzz some details in order to simplify the conceptual overview.

But, it's easy enough to make the language in question more precise:

  • Each constructor is a function that typically has a property named "prototype".
  • Every object created by a constructor has an implicit reference (called the object's prototype) that typically is set to the value of its constructor's "prototype" property.

However, it isn't clear to me that adding "typically" actually improves the over view very much. And I'm sure this isn't the only nit that could be picked from 4.2. If such nits are too objectionable, an alternative would be to completely eliminate section 4.2.

( note the second point is still only conceptual view and not 100% accurate. More precisely, every object has an internal method [[GetPrototypeOf]] ...)

Member

allenwb commented Mar 12, 2016

4.2 is summary of the language that dates to ES1 (thanks, rpg). As it states, 4.2 is a non-normative overview of the language. It's ok of it to fuzz some details in order to simplify the conceptual overview.

But, it's easy enough to make the language in question more precise:

  • Each constructor is a function that typically has a property named "prototype".
  • Every object created by a constructor has an implicit reference (called the object's prototype) that typically is set to the value of its constructor's "prototype" property.

However, it isn't clear to me that adding "typically" actually improves the over view very much. And I'm sure this isn't the only nit that could be picked from 4.2. If such nits are too objectionable, an alternative would be to completely eliminate section 4.2.

( note the second point is still only conceptual view and not 100% accurate. More precisely, every object has an internal method [[GetPrototypeOf]] ...)

@allenwb

This comment has been minimized.

Show comment
Hide comment
@allenwb

allenwb Mar 12, 2016

Member

More generally... a constructor is an object that has a [[Construct]] internal method. It isn't the case that all constructors are required to have a prototype property. That is only a requirement of some concrete [[Construct]] internal methods.

Member

allenwb commented Mar 12, 2016

More generally... a constructor is an object that has a [[Construct]] internal method. It isn't the case that all constructors are required to have a prototype property. That is only a requirement of some concrete [[Construct]] internal methods.

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Mar 12, 2016

Member

Other than Proxy, is there anything else that does not have a 1:1 relationship with [[Construct]] and .prototype?

Member

ljharb commented Mar 12, 2016

Other than Proxy, is there anything else that does not have a 1:1 relationship with [[Construct]] and .prototype?

@erights

This comment has been minimized.

Show comment
Hide comment
@erights

erights Mar 13, 2016

Other than Proxy, is there anything else that does not have a 1:1 relationship with [[Construct]] and .prototype?

const sillyCounterExample = () => {};
sillyCounterExample.prototype = 7;

erights commented Mar 13, 2016

Other than Proxy, is there anything else that does not have a 1:1 relationship with [[Construct]] and .prototype?

const sillyCounterExample = () => {};
sillyCounterExample.prototype = 7;
@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Mar 13, 2016

Member

@erights yes but arrow functions can't be constructed

Member

ljharb commented Mar 13, 2016

@erights yes but arrow functions can't be constructed

@webbedspace

This comment has been minimized.

Show comment
Hide comment
@webbedspace

webbedspace Mar 13, 2016

Then on the flip side - perhaps Proxy should have a .prototype object, even if the resulting instance doesn't use it (which is totally doable in ES3 even)?

This is a different topic, but I recently noticed the peculiarity in Proxy having [[Construct]] but no prototype allows this to occur:

class B extends Proxy {} // Error
Proxy.prototype = {}
class C extends Proxy {} // Okey-dokey
new C({}, { get() { return 8 }}) // No semantic difference from the actual Proxy constructor, though.

I was thinking that perhaps it could have a prototype property with value: undefined, writable: false, configurable: false, enumerable: false to elide this (and to restore the invariant that constructors have non-configurable non-writable prototypes).

webbedspace commented Mar 13, 2016

Then on the flip side - perhaps Proxy should have a .prototype object, even if the resulting instance doesn't use it (which is totally doable in ES3 even)?

This is a different topic, but I recently noticed the peculiarity in Proxy having [[Construct]] but no prototype allows this to occur:

class B extends Proxy {} // Error
Proxy.prototype = {}
class C extends Proxy {} // Okey-dokey
new C({}, { get() { return 8 }}) // No semantic difference from the actual Proxy constructor, though.

I was thinking that perhaps it could have a prototype property with value: undefined, writable: false, configurable: false, enumerable: false to elide this (and to restore the invariant that constructors have non-configurable non-writable prototypes).

@allenwb

This comment has been minimized.

Show comment
Hide comment
@allenwb

allenwb Mar 13, 2016

Member

Note that the default [[Construct]] internal method of ECMAScript function objects does not require that the constructor function have a prototype property.
@erights
bound functions may be constructable but do not have a prototype property
implementation defined exotic functions may be constructors but need not have a prototype property.

I don't see any need for any normative changes relating to the prototype of constructors. The spec. reflects reality as it has existed since the early days of ES.

Member

allenwb commented Mar 13, 2016

Note that the default [[Construct]] internal method of ECMAScript function objects does not require that the constructor function have a prototype property.
@erights
bound functions may be constructable but do not have a prototype property
implementation defined exotic functions may be constructors but need not have a prototype property.

I don't see any need for any normative changes relating to the prototype of constructors. The spec. reflects reality as it has existed since the early days of ES.

@erights

This comment has been minimized.

Show comment
Hide comment
@erights

erights Mar 13, 2016

@allenwb That seems right to me.

erights commented Mar 13, 2016

@allenwb That seems right to me.

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Mar 17, 2016

Member

I think 4.2 (and all of Clause 4) is a useful overview to have. But @allenwb is right, there are other nits there. Proxies especially would require lots of "typically's" to be added in various places. One possible way to avoid that is to define terms in a spec-rigorous way (Eg. a constructor is an object with a [[Construct]] slot) but that erodes much of the value of this high-level non-normative description. I think this is fine to leave as-is.

Member

bterlson commented Mar 17, 2016

I think 4.2 (and all of Clause 4) is a useful overview to have. But @allenwb is right, there are other nits there. Proxies especially would require lots of "typically's" to be added in various places. One possible way to avoid that is to define terms in a spec-rigorous way (Eg. a constructor is an object with a [[Construct]] slot) but that erodes much of the value of this high-level non-normative description. I think this is fine to leave as-is.

@bterlson bterlson closed this Mar 17, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment