On Nov 14, 2011, at 3:15 PM, David Flanagan wrote:
> On 11/14/11 3:01 PM, Allen Wirfs-Brock wrote:
>>
>>
>> On Nov 14, 2011, at 2:01 PM, Brendan Eich wrote:
>>
>>> On Nov 14, 2011, at 12:16 PM, Allen Wirfs-Brock wrote:
>>>
>>>> let Point = {
>>>> x:0,
>>>> y,0,
>>>> constructor(x,y} {
>>>> this.x=x;
>>>> this.y=y;
>>>> }
>>>> }.constructor; //<----------- note added property reference
>>>>
>>>> let p = new Point(1,2); //new operator applied to a constructible
>>>> function
>>>
>>> So can you spec operator new a bit? It tries [[Construct]] and if missing,
>>> tries for a .constructor property that it calls on a fresh instance of
>>> Object whose [[Prototype]] is the exemplar?
>>
>> Yup, that's essentially the semantics. I'm going to write up the object
>> exemplar strawman which will cover this (and also instanceof).
>>
> I have a bad feeling about making 'new' work with both functions and object
> exemplars. If we can have two different types of classes, we're going to end
> up using typeof on our class objects to figure out what kind of class they
> are. If I've got a value C from a library and I think it is an object
> exemplar, but it is in fact a constructor function, then 'class C' is going
> to return Function rather than C itself...
Well, new'ing object exemplars has always been the central concept of our
discussions about them. Essentially it is the self style of object creation
and arguably the way the prototypal instantiation is supposed to work. It
seems to be what people who really like prototypal inheritance really want to
do.
The "magic" of what I'm proposing is that you will rarely have to worry about
whether a named object abstraction (call it Foo) you get from a library is an
object exemplar or a function/class exemplar. Without knowing you can say:
new Foo(args)
and it will work. Without knowing you can do either :
let subfoo = Foo <| {constructor() {}};
or
let subfoo = class Foo <| {constructor() {}} //note this parses as: class
(Foo <| {... })
and things will work. You can even say:
let subfoo = Foo <| function() {}
and the right thinks happen.
To me, this seems like the essence of object-oreinted implementation
encapsulation. All a client of Foo needs to know is that Foo is an "exemplar"
and hence it can be instantiated (via new) or specialized (via <|). It is up
to the implementor of Foo to decide how to best express its implementation.
They can even change their mind and clients shouldn't care.
Finally, if you really need to know whether an exemplar is an object exemplar
or a function exemplar then typeof Foo is Function seems like a fine way to
test it. (I'm really growing to like the is operator...)
>
> Object exemplars does not pave the cowpaths for classes: it creates a new
> path and just smears out the concept of a class into something more broad. I
> fear it will create confusion rather than " provide a terse and declarative
> surface for those semantics so that programmer intent is expressed instead of
> the underlying imperative machinery."
I look at it from the perspective that we already have at least two cowpaths
that meander across each other in ways that make it hard to stay on either
one. I'm optimistic that we pave them in such a way that we are really dealing
so parallel lanes on the freeway (and this analogy just got totally out of
hand).
Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss