A strawman for subclassing

David Bruant david.bruant at labri.fr
Wed Jun 15 08:17:57 PDT 2011


Le 15/06/2011 16:43, Mark S. Miller a écrit :
>
>
> On Wed, Jun 15, 2011 at 7:17 AM, David Bruant <david.bruant at labri.fr 
> <mailto:david.bruant at labri.fr>> wrote:
>
>     Le 14/06/2011 07:04, Mark S. Miller a écrit :
>>
>>
>>     On Mon, Jun 13, 2011 at 5:08 PM, David Bruant
>>     <david.bruant at labri.fr <mailto:david.bruant at labri.fr>> wrote:
>>
>>         Le 14/06/2011 01:24, Allen Wirfs-Brock a écrit :
>>         > On Jun 13, 2011, at 3:46 PM, David Bruant wrote:
>>         >> Hi,
>>         >>
>>         >> The subclassing native constructor issue came out several
>>         times on the
>>         >> list and on the web. However, I do not see a strawman for
>>         this. There
>>         >> are strawman:array_create and strawman:array_subtypes, but
>>         no mention of
>>         >> a generic solution.
>>         > The <| operator is the proposed solution.
>>         Oh ok, sorry, I hadn't read it yet. Thanks.
>>
>>         > Using <|  instances with arbitrary [[Prototype]] values can
>>         be created for any type built-in object type that has a
>>         literal representation.  that is functions, arrays, regexps,
>>         and less interestingly, strings, numbers, booleans.  The
>>         resulting instance all have the appropriate special internal
>>         behaviors that are associated with the built-in types.
>>         It requires the right-hand side to have a specific initialization
>>         syntax. It currently works for all the "classes" you cited
>>         ("functions,
>>         arrays, regexps, and less interestingly, strings, numbers,
>>         booleans"),
>>         but does not for the current harmony:simple_maps_and_sets for
>>         which
>>         there is currently no specific syntax. Consequently, these
>>         could not be
>>         subclassed (or I am missing something).
>>         This would be the case for any other native "class" that
>>         wouldn't such
>>         syntax. I'm not sure it's is viable in the long term because
>>         it will
>>         require all subclassable (something people will want to subclass)
>>         "classes" to have a syntax.
>>
>>         I like the idea of the <| operator, but a generic non-syntaxy
>>         solution
>>         would be good too in my opinion. It would also allow people
>>         to subclass
>>         host constructors (host objects with [[Construct]]).
>>
>>
>>     We have noticed this issue, and an draft of the classes proposal
>>     attempted to address it. What's left of that, at
>>     <http://wiki.ecmascript.org/doku.php?id=harmony:classes#constructor_chaining>
>>     is:
>>
>>     These semantics for constructor chaining preclude defining
>>     classes that inherit from various distinguished built-in
>>     constructors, such as Date, Array, RegExp, Function, Error, etc,
>>     whose |[[Construct]]| ignores the normal object passed in as the
>>     this-binding and instead creates a fresh specialized object.
>>     Similar problems occur for DOM constructors such as HTMLElement.
>>     This strawman can be extended to handle such cases, but probably
>>     at the cost of making classes something more than syntactic sugar
>>     for functions. We leave that to other strawmen to explore.
>>
>     I think that saying "whose [[Construct]] ignores the normal object
>     passed in as the this-binding and instead creates a fresh
>     specialized object." is misleading. It seems to imply that the
>     internal [[Construct]] method of an object always create a "normal
>     object". It is not true. Internal [[Construct]] of native
>     functions (ES5 - 13.2.2) create a normal object (step 1), but
>     there is no constraints for other objects with an internal
>     [[Construct]] to do so.
>     Namely, Date, Array, RegExp, Function, Error have a different
>     approach to [[Construct]]. Host objects aren't This difference is
>     further emphasis with Harmony proxies which have the ability to
>     provide two completely different functions to
>     Proxy.createFunction(handler, call, construct).
>
>     By the way, slightly above the paragraph you quote is written:
>     "Within the body of the constructor, an expression super(x, y)
>     calls the superclass’s [[Call]] method with thisArg bound to this
>     constructor’s this and the arguments x and y."
>     Why has [[Call]] been chosen over [[Construct]]? The latter makes
>     much more sense in the context of inheritance in my opinion. And
>     if I ask "A extend B" and B is a function proxy for which I have
>     provided a custom [[Construct]], I expect this one to be called,
>     not [[Call]].
>
>
> As [[Construct]] is currently defined, you can't pass in an already 
> constructed object for it to further initialize. So it doesn't make 
> sense for constructor chaining to call the superclass' [[Construct]], 
> even if the superclass is a function proxy.
Hmm... I think that it's because most current [[Construct]] (ES5 - 
13.2.2) have steps 1 and 9-10. As far as I know, on ES5, [[Construct]] 
is only used in the "new" operator; Would it make sense to move steps 1, 
9 & 10 to the "new" operator definition (ES5 - 11.2.2)? The object would 
be passed as the 'this' binding of [[Construct]]. It would allow to 
create different objects on step 1 depending on context (for instance if 
the constructor has been created in a "class"-syntax defintion, the 
object may inherit from something else than Object.prototype). I don't 
think it would affect how the "new" operator currently works.

Now that I think about it, there is a weird difference between [[Call]] 
and [[Construct]]. The former has a 'this' binding and the latter 
doesn't. Considering the object being constructed as a 'this' binding to 
[[Construct]] could allow what you said ("pass in an already constructed 
object for it to further initialize") by passing the same 'this' object 
to several [[Construct]].

Does this change sounds feasable?

Regardless of this change, I think I understand that there is some issue 
with wanting a class syntax and inheriting from built-in/host 
constructors. Not because of [[Construct]], but because of the custom 
Meta Object Programming contract.

David
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110615/07a7971d/attachment-0001.html>


More information about the es-discuss mailing list