On Jun 28, 2011, at 8:34 PM, Bob Nystrom wrote:

> I like the simplicity of this, but I'm not crazy about how it merges two 
> distinct objects into one. TodayJS (and most class-based languages) let you 
> distinguish two things:

(actually in the today's most widely used class-based languages (Java, C#, C++) 
a "class" is no an object at all and don't have properties/fields/polymorphic 
methods/etc.  they really are just a scoping mechanism.  What you are saying is 
more typical of many dynamically typed class-based languages).

Note that the goal of the prototype as classes proposals is not to turn JS into 
more of a class-based language.  Instead it was to solve the same problem that 
classes solve but in a manner that returns JavaScript closer to its original 
prototype-based roots.  This was covered in  the message that started the 
"Prototype as new new class declaration" thread 
https://mail.mozilla.org/pipermail/es-discuss/2011-June/015135.html  It is 
probably worth while going back to review those first few messages to get a 
better chance of what this proposal is really about.

While both the class-based approach and the prototype-base approach allow you 
to describe an open ended set of similar objects via a named abstraction, the 
key difference is in what you name.  In the class based approach you name the 
object that is responsible for creating new instances (the constructor) of the 
set. In the prototype-based approach you name the prototypical instance of the 
set. 

The "two objects" you speak of is purely an artifact of how the class-bassed 
approach works.  It is not a fundamental characteristic of all OO languages.  

When it is useful to have s separate factory object for creating the instances 
of a prototype-based abstractions, prototype-based languages simply create 
another object to act as the factory. that object can have private state, 
addiional public properties for accessing canonical instances, etc. 

In https://mail.mozilla.org/pipermail/es-discuss/2011-June/015195.html  is 
examine how the self language addressed various situations where "static 
methods" might be used in a class-based langauges.


> 
> 1. A set of properties relevant to the class itself.
> 2. A set of properties shared by each instance of the class.
> 
> In a class-based language, #1 up there is "static" methods and fields. So 
> when you do something like this in Java:
> 
>   Integer.parseInt("1234");
> 
> The "parseInt" method isn't a method that you can call on an integer, it's a 
> method you call on the Integer class itself.

In self, you would likely do exactly the above.  Integer would be the name of 
the prototypical integer object and that object would have a method named 
parseInt.
You then can just say: 
   Integer.parseInt("1234");    //actually in self you would say: Integer 
parseInt: '1234'.
or you can say
    0.parseInt("1234");
or any other integer object that was conveniently available.

If you didn't want the ability to parse to be a method of integers you would 
just create a factory object:
    IntegerBuilder.parse("1234");

Why is this worse than a "static method"?

> 
> In Javascript, those are properties on the constructor:
> 
>   function Point(x, y) {
>     this.x = x; this.y = y;
>   }

note that the above isn't a property of the constructor, it is the constructor. 
 It actually is a property of the prototype.

> 
>   Point.zero = function() { return new Point(0, 0); }
> 
>   Point.zero(); // "static" method.

 It's all a mater of how you think of responsibilities.  In a consistent 
prototype based usage, the "zero" point would probably actually be the 
prototypical point in which case you would access it simply as Pointl 


> 
> The second set of properties are properties on ".prototype" in JS: Its
> 
>   Point.prototype.flipX = function() {
>     this.x = -this.x;
>   }
> 
>   var p = new Point(1, 2);
>   p.flipX();
>   p.x // -1
> 
> To me, those two sets are utterly distinct. This code looks pretty strange:
> 
>   Point.flipX(); // What x?
The x of the prototypical point named Point.  As a prototypical point it has 
all the properties of any other point instance including an x and y property.
(I'm ignoring the fact the a point abstraction with mutable x and y fields is 
probably not a very good design).

In practice, you probably wouldn't call such a method on the prototype, so you 
wouldn't see the above at all.  But you could, that's what it means to be a 
prototype-based language.

> 
>   var p = new Point(1, 2);
>   p.zero(); // This works, but what does it have to do with 'p'?

probably as much as any other Point method that creates a new instance.  Since 
you probably really do want to have immutable points, that means most point 
methods:

  p.add(new Point(3,4)); //returns a new point with x=4, y=6
  p.zero();                          //return a point with x=0,y=0

But, similar to above, in practice you probably would seldom actually see the 
latter. You would just see:
  Point.zero();

> 
> Your proposal would allow that, I think. For example, starting from yours:
> 
>   // Superclass
>   var Person = {
>       constructor: function (name) {
>           this.name = name;
>       },
>       describe: function() {
>           return "Person called "+this.name;
>       }
>   };
> 
> I could do:
> 
>   var bob = new Person("Bob");
>   bob.constructor("Fred"); // I guess I'm Fred now.
> 
> Does the above seem strange to you too?

not particularly anymore so than
   Bob("Fred");    //note no new
or
   Bob.call(bob,"Fred")

Allen
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to