Using Object Literals as Classes

Herby Vojčík herby at
Sat Mar 17 13:20:00 PDT 2012

Allen Wirfs-Brock wrote:
> On Mar 17, 2012, at 8:39 AM, Claus Reinke wrote:
>>>> 1. I don't like the imperative approximations of a declarative API.
>>>> Since we're designing new language features, approximations
>>>> should not be necessary.
>>>> There have been suggestions to interpret '<|' declaratively,
>>>> and to avoid the special case for function rhs, ie, to interpret
>>>> (p<| obj) simply as a structural representation of an object with
>>>> un-nameable '[[prototype]]' field containing p.
>>> You mean ditching function RHS completely or just not having it to specially treat LHS being function as well?
>> Neither. Currently,<| sets the [[prototype]] field of the RHS object,
>> and -if the RHS is a function literal- also specifies the [[prototype]]
>> field of objects generated from it. I suggest to remove that special
>> case for function RHS.
>>>> What were the arguments against this?
> (function () {}) creates two object, not one. We have to set the
> [[Prototype]] of both objects to something.  In deciding how to do
> this it is important to look at the role of each  member of that
> object pair.  The existing language defines a relationship between
> them that we need to respect.  We also need to consider what is going
> to be least surprising to users given the most common usage
> patterns.
> Consider
> let F1 = function() {}; = "foo"; = "bar"
> let F2 = Fi<| function() {};
> will a ES programmer expect be be "foo" or undefined.
> Understanding that<| defines the [[Prototype]] of the the function
> they should expect "foo".
> What about (new F2).bar will they expect "bar" or undefined. This is
> probably not something that they have thought about before, but I'm
> pretty confident that they will be astonished if they get undefined
> instead of "bar"
> This has nothing to do with classes.  It is just basic prototypal
> inheritance and the semantics of the new operator and function
> expressions.

Well, seems convincing... but nevertheless, I see it as a strange 
special case... maybe good example is "bare"

   function foo () {}

How would you write it using <| ?

If you do

   Function <| function foo () {} // [[Prototype]] set right

you get wrong prototype.[[Prototype]]. If you write

   Object <| function foo () {} // prototype.[[Prototype]] set right

you get wrong [[Prototype]].

So it _has_ to do a lot with classes... anything taking 'new foo' into 
account is taking classes into account.

That's why I think <| should not set prototype.[[Prototype]] at all. 
Plain functions then can be written

   Function <| function foo () {} // *

and double chain (classical class inheritance) can be provided by 
different syntax, for example one I hinted:

   function Bar () extends Baz {}

> Allen


* I know there is no real point in writing bare constructor functions 
using <| at all - but it illustrates for me the problem - it cannot 
embrace this trivial scenario, so ... it hints it may be problematic.

More information about the es-discuss mailing list