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

