On Oct 29, 2011, at 10:03 PM, John J Barton wrote:

> On Sat, Oct 29, 2011 at 4:34 PM, Axel Rauschmayer <[email protected]> wrote:
>> http://wiki.ecmascript.org/doku.php?id=harmony:object_extension_literal_class_pattern
>> 
>>    const className = superClass <| function(/*constructor parameters */) {
>>        //constructor body
>>        super.constructor(/*arguments to super constructor */);
>>        this.{
>>         //per instance property definitions
>>        };
>>    }.prototype.{
>>        //instance properties defined on prototype
>>    }.constructor.{
>>        //class (ie, constructor) properties
>>    };
> 
> I totally appreciate Allen's effort to build coherence around the
> operator-to-be-named-curiously triangle.
> 
> For me this form is confusing compared to a class-based language.  A()
> should construct A-s, A.foo() should be a method of A-s.
> Prototypical classes should have a prototype as their super class.

A fundamental difference between prototype languages (for example self) and 
class-bassed dynamic languages such as Smalltalk and Ruby is that the 
class-based languages have two, roughly parallel, inheritance hierarchies for 
each "class".  Instances of a class inherit superclass instance behavior while 
the class objects themselves inherit behavior from the superclass objects.  
These are independent inheritance chains.

(see chapter 13 of 
http://gforge.inria.fr/frs/download.php/25599/PBE1-2009-10-28.pdf ) of an 
excellent explanation of such parallel hierarchies)


      superClass <| function ...
is also setting up two parallel inheritance chains.  the function expression is 
creating a new "class object" (which in JS we also refer to as a "constructor") 
which inherits its behavior form the class object (ie, a constructor) 
superClass.  The instance behavior of the new "class" is defined by the the 
prototype object associated with the new class (instances inherit from the 
prototype object).  The prototype object inherits from the prototype associated 
with superClass. 

> 
> But here we have a .prototype defining instance properties. I guess
> every JS dev is puzzled by .prototype already. Compared to a class
> language, it seems like a hack. Do we really need it?

this is one of the differences between prototypal and class based languages.  
In prototypal languages the methods that are shared by all instances of an 
object abstraction explicitly exist in the "prototype object" and can be 
directly observed and manipulated at runtime by the programmer..  Class based 
languages store the shared instance methods in a typically invisible data 
structure (a "method dictionary"). Usually a reflection API has to be used to 
view or manipulate the content of this data structure at runtime.

JS is what it is.  I don't think it is possible to make prototypes disappear 
without breaking many (most??) existing JS programs. 

> 
> I'd love to see a riff on Gozala's selfish with the declarative
> approach. Maybe the gap is too large.

It has been proposed in many variations.

The basic way that object abstractions are instantiated in the self language is 
via a copy/initialize sequence.  You send a copy message to a Prototype object, 
typically this creates a new object that inherits form the Prototype and then 
invokes the initialize method on the new object to set up and instance specific 
state.

In selfish, the "new" method is the equivalent of self's "copy" method and 
selfish's "initialize" method serves a similar role to self's "initialize" 
method.  If you have to define a lot of methods (typically because the object 
you are defining is going to be used as a Prototype), it's inconvenient  to do 
this in the initialize method, so both self and selfish provide a way to 
directly define a new Prototype object.  In self, this is via its IDE and 
reflection API.  In selfish it is via the "extend" method.

The "object exemplar" proposal I have talked about also exactly parallels this 
same self/selfish model.  With object exemplars, the JS new operator 
corresponds to self's "copy" and selfish's "new" method. With object exemplars 
the "constructor" method corresponds to the self/selfish "initialize" method.

So where in self you would:
   Derive a new prototype object named Dog from a prototype named Mammal using 
the IDE.
   Create a Dog instance by saying:
         Dog new: 'Labrador'
    which creates a new object that inherits from Dog.  The "initialize method 
is invoked on the new instance passing "Labrador" as the argument. 

In selfish you would:
  Derive a new prototype named Dog by evaluating:
         var Dog = Mammal.extend ({
              initialize: function(breed) {this.breed = breed},
               /* other dog methods */
          });
   You would create a Dog instance by saying
        Dog.new("Labrador")
    which creates a new object that inherits from Dog.  The "initialize" method 
is invoked on the new instance passing "Labrador" as the argument. 

 In JS using my object exemplar proposal you would:
  Derive a new prototype named Dog by evaluating:
         var Dog = Mammal <| {
              constructor: function(breed) {this.breed = breed},
               /* other dog methods */
          });
   You would create a Dog instance by saying
        new Dog("Labrador")
    which creates a new object that inherits from Dog.  The "constructor" 
method is invoked on the new instance passing "Labrador" as the argument. 


The object exemplar approach is just like self or selfish, except that it 
builds upon features that are already in JS.  Specifically, it uses the new 
operator instead of a new method and it names the initialization method 
"constructor" in order to tie into the object construction mechanisms that 
already exist in JS. 

Allen











> 
> jjb
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
> 

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to