Summary: prototypes as classes

Bob Nystrom rnystrom at google.com
Tue Jun 28 16:41:00 PDT 2011


On Tue, Jun 28, 2011 at 3:56 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>
wrote:
(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).

Understood. That's why I used the vague "set of properties" to describe
static methods in class-based languages. A class may not be a first-class
object (and there may not be a metaclass for it) but it still has a set of
methods associated with it for some loose definition of "associated".

> 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.

I have two responses to that:

You're right that it's an artifact of how the class-based approach works,
but I look at that as a positive sign: that artifact represents the choice
of many popular languages (and lots of idiomatic JS code for that matter).
If the cow-path is that well-worn, it may be worth paving it, or at least
tossing a bit of gravel down.

But, more abstractly, I do think there are two fundamentally different
"objects" here. Some operations, conceptually, relate to a kind of object,
but don't relate to any specific instance of it. Others are specific to a
single instance.

We can lump those operations together (and hope they don't collide), but I'm
having trouble seeing why we'd want to.

> 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.

I think the lesson from lots of languages (including JS) is that those
factory objects are pretty handy. Why move away from them?

> or you can say
>     0.parseInt("1234");
> or any other integer object that was conveniently available.

When I see code like:

    somePoint.flipX();

That implies to me that flipX() uses somePoint's state in some significant
way. If it didn't, why is somePoint receiving the message and not some other
object? So when I see:

    0.parseInt("345");

I feel like the code is misleading the reader. Why am I sending "parseInt"
to 0 if it doesn't have anything to do with it?

> 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"?

Who said it was? Factory objects are swell. I just don't see why instances
should inherit from them. In some general sense, a point in space at (3, 2)
is not a point factory, it's a point. Why should it inherit from an object
that represents a point factory?

>>  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.

Heh, understood. I was referring to the stuff *after* that bit. :)

> 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

I do realize that, and for very simple types like (immutable) points, that
model works pretty well. I'm not sure what the prototypical image would look
like (Lena?), or what the prototypical mailing address is (123 Main
Street?).

> (I'm ignoring the fact the a point abstraction with mutable x and y fields
is probably not a very good design).

I wouldn't be too eager to ignore things like that. People using our
languages may not be the best designers but they still want to get their job
done. If prototypes-as-classes help, that's awesome, but if it's just a gun
that auto-aims for their feet we haven't done them any favors.

> But you could, that's what it means to be a prototype-based language.

Well, that's what it means to be a prototype-based language *and* follow a
certain inheritance pattern. I don't think I'm arguing against prototypes.
I'm just not sold on making the object bound to the class name be the
prototype of instances of that class.

>From my view, JS-of-today is no less prototype-based than what Axel is
proposing, it just wires things up a bit differently. Or is there something
I'm missing?

- bob
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110628/d4b75ed1/attachment.html>


More information about the es-discuss mailing list