

Prototypes Are Not Classes - raganwald
http://raganwald.com/2014/01/19/prototypes-are-not-classes.html

======
kyberias
The author has to emphasize that prototypes and classes are a different
concept at least five times in the article. Why? Because the explanation is
long-winding and weak.

~~~
raganwald
This is the best feedback so far.

~~~
pygy_
How about this for an abbridged version?

 _" You can add methods to any objects (no metaclass required), and any object
can be inherited form, becoming the prototype of its descendants. In other
words, any object can perform the job of a class in a class-based language."_

~~~
dognotdog
TL;DR: long winded bad analogy, but maybe helpful

That doesn't sound _quite_ right to me. Not that it is wrong, but maybe
looking at it the wrong way?

For the discussion, I propose an object has some state, and can receive
messages and send messages in response.

A class is the abstract idea of what an object should be like. To break out
the bad analogies, it's like ordering from a restaurant menu. You ask the
runtime for an instance of a class. If you want something special, you have to
have it put on the menu first. Prototype restaurants have no menus, but they
have the dishes on display, and you can order those. Or, if you're so
inclined, just point at your neighbours' food and order what that guy's
having. If he's eaten half of it already, you'll only get as much as he has
left, but luckily you can add combine it with other dishes or ingredients as
you go.

You can see that if we put some rules in place about which objects can be
copied, and what happens during copying exactly, and we call some special
objects classes, and use them to create other special objects we call
instances, a prototype-based object system can be made to behave like any
class-based object system. If we bake those special rules into the language,
we make the computer's job easier with hard-wired shortcuts.

------
roel_v
Every time someone tries to explain why prototypes are so very much not
classes, I can't help but come away thinking 'yeah potato/potato - so they're
basically the same'. Be it Crockford, this guy, any of the 100 articles you
find only when you go looking for it. Sure the nuances between languages are
different, big deal - what is called 'class' in a dynamic language is very
different from what is called 'class' in C++, yet everybody calls them classes
and doesn't go around writing articles about how runtime-modifiable object
blueprints _really_ are fundamentally different from those that are set in
compile time.

~~~
raganwald
Did you read TFA or simply fold it into an airplane and launch it towards the
dustbin?

1\. This is not a dynamic vs. static thing, the languages cited in the article
with classes are all dynamic languages. Metaobjects are typically found in
dynamic languages like Common Lisp and Smalltalk.

2\. The difference between a class as described in this article and a
prototype is the same as the difference between a C struct or Pascal record
and a Smalltalk object. I do recall people saying "potato/potato" about that
when OO was first going mainstream, but I think over time people accepted that
encapsulating private state is more than a nuance.

Your Milage May Vary.

~~~
roel_v
Yes I did read it, several times even, because I _really_ want to understand
it if there is a difference. This is why I could remark what I did - because
I've actively looked into explanations of the difference, several times, over
the last year or so, and walked away with the same conclusions every time.

My point is that the more I try to understand other people's explanation, the
more I think it's just semantics. To put it in your terminology as used in
your post, it seems that you are redefining what is commonly and in a broad
sense known as 'classes' as 'metaobjects' as a generalization of different
ways to implement classes. Which is fine, when you look at the details, but to
me the difference doesn't warrant overloading a well-known term like 'class'.
(Although I'm still not clear what you'd call a C++ class, if it's not a meta-
object as your reply suggests.)

To stay with your C/Pascal vs Smalltalk example - I'd be perfectly fine
calling a C struct a 'class' when doing object-oriented C, for example as done
in GObject (from GLib, one of the Gnome base libraries), and calling a
Smalltalk class also 'class'. 'class' is a malleable OO concept, and its exact
implementation isn't all that important or interesting conceptually, and is
certainly not tied to one specific implementation of the concept. I still
don't see how the Javascript 'implementation' (I put this in quotes because
most things in Javascript are just accidents derived from design decisions
that put a high premium on ease of implementation, which BTW is usually how I
like it, I'm not knocking on JS for that here) of classes is so different that
it warrants its own name ('prototype'), suggesting it's completely different
from 'classes' (and not only that suggestion, but also people claiming that
they're 'very' or 'fundamentally' different - not saying your claim is that
strong, I can't really tell from the post, just that some people do).

------
rtpg
This sort of realization is the first step to realizing that you really
shouldn't be writing javascript like java/C++. It makes things feel a lot
nicer when you start really thinking in JS. I'd recommend checking out
Crockford's "Crockford on Javascript" series for some good intro on thinking
about Javascript
([http://www.youtube.com/watch?v=JxAXlJEmNMg](http://www.youtube.com/watch?v=JxAXlJEmNMg)).
Section 3 is where you really start talking about JS.

For a good counter-example, check out a lot of google's JS libs (in all their
giant module goodness).

------
Jare
I've never heard anyone, experienced or newbie, say "JavaScript has classes".
People at best will say "You can sort of make classes in JavaScript using
objects".

To me a Class has always been "a family of objects with the same structure and
behaviour, and a way to create them". Stuff like hiding, constructors, type
checking, polymorphism and inheritance are interesting, but secondary details.
But then, I was taught OOP using Modula-2 back in '89, so I'm used to the idea
that language features and paradigm features need not match 1:1

~~~
roel_v
Your first and second paragraph seem contradictory to me. Javascript, through
what is called 'prototypes', _has_ "a family of objects with the same
structure and behaviour, and a way to create them", and varies only in
implementation and semantic details from other languages. So I agree with your
second paragraph and would say that JS _does_ have classes, but then I'm not
sure what your first paragraph means.

~~~
Jare
You can use objects and prototypes to build classes, but they are not classes
by themselves. Similar to how you can use objects to create a linked list, but
the language itself does not have linked lists.

------
CrossEye
I think there is a serious problem in vocabulary. Wikipedia's definition of
class ([1]) is quite reasonable, which, slightly paraphrased, reads, "A class
is an extensible template for creating objects, providing initial values for
state and implementations of behavior." While typically we don't use prototype
objects for default state in Javascript, we always __can __if we choose, and
they are widely used for providing behavior. And both "extensible" and
"template" fit well. So by this definitions, prototypes really are classes.

But almost everyone who comes to Javascript from a class-based language brings
a number of additional preconceptions. I don't know the Ruby community well
enough to know if your descriptions are accurate, but I know that many of
those coming from Java or C# backgrounds expect classes to be (1) distinct
creatures from objects (and those who know much about the reflection class
Class understand that the objects of that class are objects and not the
classes themselves), (2) design/development/compile-time abstractions separate
from the run-time realities, (3) unchanging at runtime (which is obviously
different from Ruby), and (4) the enforcers of access policies of instance
methods. None of these things are true for Javascript prototypes. So to these
people, it's easiest to explain that Javascript does not have classes.

I have never implemented a serious programming language. But I understand from
those who have that implementing classes and implementing prototypes can be
very, very similar processes. So, while I won't stop insisting to those from
other languages that Javascript doens't have classes, I do recognize that I'm
talking more to their preconceptions and not to the deepest truth I know.

    
    
      [1]: http://en.wikipedia.org/wiki/Class_(computer_programming)

------
lispm
Jesus, the language is called Smalltalk. Not SmallTalk.

Btw., in a typical language supporting prototypes, I would expect that
prototypes are nothing special. Every object could be a prototype for
others...

~~~
klibertp
That's true in JavaScript - there's an Object.create() method, which creates
new object with any other object set as prototype:
[https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/Object/create)

There is a problem with accessing prototypes of objects, as they are not
exposed to the user and only available through internal property __prototype__
(IIRC). And there's quite a bit of magic involved with constructor prototypes,
which - again - makes it impossible to traverse prototype chain unless you
create your objects yourself and store the references yourself.

So yeah, prototypes are nothing special in JS, but their API kind of sucks and
could get better. Object.create is a step in the right direction IMO.

~~~
masklinn
> There is a problem with accessing prototypes of objects, as they are not
> exposed to the user

Actually, Object.getPrototypeOf was added in ECMAScript 5.1. It's even
supported by IE9.

> only available through internal property __prototype__ (IIRC)

It's an external property (the internal one is `[[Prototype]]`_, and is called
`__proto__`. It's non-standard, although all modern browsers implement it
(even IE11, but not IE10)

~~~
klibertp
> the internal one is `[[Prototype]]`

I was thinking about this one.

> Actually, Object.getPrototypeOf was added in ECMAScript 5.1.

Wow. Thanks, I wasn't aware of this.

------
pjmlp
I guess before learning JavaScript, developers need to be sent to a Self
learning camp.

~~~
masklinn
I'm not sure that's a good idea, because then they'd be made very sad by
constructors, by prototypes being something completely different[0], by not
having mixins[1], by single-inheritance, by dynamic inheritance[2], by the
lack of blocks (and non-local returns), etc…

Essentially, by javascript not being a very good Self.

[0] IIRC in Self the prototype is the object you copy, objects linked through
parent slots are either mixins or traits.

[1] although it doesn't have a lobby, which makes the difference between
traits and mixins, js's prototypes are probably closer to self's traits.

[2] that's being added in ES6, yay. But still single, boo.

~~~
angersock
MI still sends shivers down my spine, having spent time in the C++. Just say
no.

~~~
clhodapp
So C++ got multiple inheritance wrong... That doesn't mean it must be rejected
in all cases.

~~~
angersock
What are the cases where MI is better than mix-ins or component architectures?

~~~
raganwald
NewtonScript had a neat concept of heterogeneous multiple inheritance: Its
"objects" had a prototype-like inheritance chain and a container inheritance
chain.

If client-side JavaScript had this design, there would be no need for the DOM
to have a special event mechanism that lives outside of method handling: DOM
elements would simply have method handlers and the dispatch system would
handle prototype and container inheritance.

~~~
lispm
> NewtonScript had a neat concept of heterogeneous multiple inheritance: Its
> "objects" had a prototype-like inheritance chain and a container inheritance
> chain.

See also HyperCard/HyperTalk...

------
mlex
I hate to be _that_ guy, but I found the grey on light-grey text to be
difficult to read.

------
egil
Yet another shallow article describing the difference between prototypes and
classes. Does anybody know of more in depth ones that also discusses multi-
leven inheritance, polymorphism etc?

~~~
raganwald
polymorphism is actually orthogonal to the ideas around metaobjects like
classes. They are both powerful ideas. but can be expressed in different ways.
Languages like Common Lisp and Haskell allow you to express polymorphism
entirely through overloading of functions, for example.

------
CmonDev
Good (enough) for GUIs, bad for business logic.

------
ossdev1
Never get why people are so excited with atomization, that necessity of
decomposing everything in atomic parts...

~~~
raganwald
Some people just want to watch the world burn.

Others are curious. What is fire? Is electricity fire? What's the smallest
thing That can be on fire? How can you make something burn faster?

We make up little explanations about how knowing the answers to these
questions makes us more productive world-burners, but in the end we're just
curious people.

