My ECMAScript 7 wishlist

Tab Atkins Jr. jackalmage at gmail.com
Thu Sep 25 11:56:14 PDT 2014


On Thu, Sep 25, 2014 at 11:08 AM, Brendan Eich <brendan at mozilla.org> wrote:
> Tab Atkins Jr. wrote:
>>>
>>> Ok, let's not hand-wave mixin syntax, though (Andrea hacks __proto__).
>>> What
>>> >  API do you prefer?
>>
>>
>> I'm partial to magic-named functions, but that's probably my
>> experience speaking, rather than a more thoughtful opinion.
>> Symbol-named magic functions would be better, since we have those and
>> most other languages don't.
>>
>> Andrea wasn't even hacking __proto__ - they're just adding it to the
>> class prototype, so newly constructed objects'll have it.
>
>
> Right, __noSuchProperty__ -- I was an Andrea post behind.
>
> How is this easier to compose than adding a proxy object on the prototype
> chain just before Object.prototype?

Adding an object to the prototype chain requires you to modify your
class hiearchy.  If you add it at the very top (before
Object.prototype), this means that you're affecting every class in the
tree, even if you meant to only target a single class somewhere
further down.  If you try to add it in a targeted way in the middle of
your hierarchy, it requires either __proto__ hacking, something like:

class superclass {...}
...
x = makeNSPProxy()
x.__proto__ = superclass()
class subclass extends x {...}

With this, you lose the implicit information about the actual
superclass/subclass information.  The Proxy isn't actually a
superclass in any semantics sense, it's just something you're shimming
in because you need to hijack property lookups and the prototype chain
is where we go when we can't find a property.

But of course, this doesn't work either - it'll catch properties that
*are* defined further up the prototype chain.  So you're stuck with
either applying it to every class, or doing *further* __proto__
hacking, to walk the object's proto chain on instantiation and install
the Proxy as a top-most proto, or installing it as top-most prototype
for everyone but doing type checks on instances to make sure it only
fires for the classes you want.

On the other hand, a magic property can be placed exactly where you
want it, without any difficulty.  It can be added to individual
objects with the same difficulty as adding it to an entire class, or
class hierarchy.  It doesn't require leaning about Proxies (a very
complicated topic!) and Reflect to learn how to properly implement it
by overriding the correct traps, and not accidentally over-trapping.
It's a very simple way to do something that's very often desired, and
easy to do in many languages.

Basically, I think the group has trapped itself in a "it's technically
possible already, why do we need to do anything?" trap, which is easy
for a lot of web platform people to fall into these days. :/

>>> >  Or did you want `sealed class` or other such syntax, and I
>>> > misunderstood?
>>
>>
>> Nah, using superclasses in general is the bad thing here; it doesn't
>> compose well without multi-inheritance, which JS likely isn't going to
>> do.
>
>
> Adding a magic-name property in the prototype chain is topologically no
> different (assuming no collision on the name, and no dead-reckoning by
> distance along prototype chain [which is considered brittle already]) from
> extending the prototype chain.
>
> Instead of asserting "bad thing" and "inappropriate", can you show where the
> difference between the two (magic name vs. magic prototype) matters?

Topological similarity and practical similarity aren't always similar,
topologically or otherwise.  Hopefully I've demonstrated it above.

~TJ


More information about the es-discuss mailing list