Summary: prototypes as classes (PaCs)
On Jun 28, 2011, at 4:12 PM, Axel Rauschmayer wrote:
Explaining constructors-as-classes is really hard, explaining subclassing is even harder.
This really depends on the student's background and previous experience. It is not universally true.
I bet that in the coming year more new people are going to learn JavaScript than everyone who knows it now. We have to plan for former group, not for the latter.
You can't assume the newcomers have no experience with other classy languages, though. Many do, and PaCs are more confusing (few Self students out there).
Explaining constructors-as-classes is really hard, explaining subclassing is even harder.
This really depends on the student's background and previous experience. It is not universally true.
True, but it’s the experience I’ve had so far (explaining JS to friends). And there were no Selfers (I wouldn’t even consider myself one).
Do students who prefer constructors really understand and use prototypes properly?
What I usually see is something like this:
function C(x, y) { return { x: x, y: y, doSomething: function() { ... } }; }
That is indeed easier to understand than PaCs. It only becomes complicated when you move shared data into the prototype. And when you subclass.
There might be enough other obstacles to prevent PaCs from happening, but: Is there a way to test whether constructors or PaCs are easier to understand for newbies? For example: Give a few JS newcomers a description of both PaCs and constructors and let them rate both proposals with regard to ease of understanding?
What would be the question to ask, e.g. after someone has read my blog post? “Which do you find easier to understand – constructors or prototypes-as-classes?” Problem: Finding descriptions that don’t have bias.
At any rate, I really want to see Allen’s proposal (once it is finished).
What do you do with constructors-as-classes to check the following? o instanceof C You look for C.prototype in the prototype chain of o.
No, the JS engine does that!
I, or random classy-dynamic-language-experienced users, just do "o instanceof C", i.e., they ask "is o an instance of [constructed by] C"?
Not everyone mentally deconstructs operators into their more primitive semantics.
But with PaCs you don’t have to deconstruct, there is no detour from the class to another construct.
Especially if there's no prototype-chain hacking, just shallow classical inheritance via a solid library.
Then we would have a Python-like abstraction on top of current facilities. Which I don’t mind at all. But I’m worried about the abstraction leaking.
If prototypes already make it all work in the background, why not try and make do just with them?
On Jun 28, 2011, at 5:30 PM, Axel Rauschmayer wrote:
What do you do with constructors-as-classes to check the following? o instanceof C You look for C.prototype in the prototype chain of o.
No, the JS engine does that!
I, or random classy-dynamic-language-experienced users, just do "o instanceof C", i.e., they ask "is o an instance of [constructed by] C"?
Not everyone mentally deconstructs operators into their more primitive semantics.
But with PaCs you don’t have to deconstruct, there is no detour from the class to another construct.
I just wrote that with classes or today's constructor functions, no one has to deconstruct, either.
On the other hand, having PaCs and classes/constructors is more complex than just having one. And we do not get the choice of just having PaCs.
Especially if there's no prototype-chain hacking, just shallow classical inheritance via a solid library.
Then we would have a Python-like abstraction on top of current facilities. Which I don’t mind at all. But I’m worried about the abstraction leaking.
What leak? We want sugar for today's patterns. I think you keep assuming everyone thinks about prototypes not constructors, but that is not universally true -- far from it.
But with PaCs you don’t have to deconstruct, there is no detour from the class to another construct.
I just wrote that with classes or today's constructor functions, no one has to deconstruct, either.
Sorry, I meant there is nothing more going on behind the scenes. I remember when I first read about instanceof, I couldn’t figure out how that operator could connect an instance to its constructor (that was before I knew about the “constructor” property which could in principle be used for this purpose). Then I read how this operator was handled internally and everything made sense.
On the other hand, having PaCs and classes/constructors is more complex than just having one. And we do not get the choice of just having PaCs.
True!
=== Class methods becoming instance methods ===
I agree: This one point is weirder with PaCs than with constructors. It would be great if global variables (as in “the global object”) wouldn’t have to be an instance of Object.
Two mitigating factors:
=== Target audience ===
I can accept compatibility with existing code as an argument in favor of constructors, but not that that’s what people are familiar with.
Explaining constructors-as-classes is really hard, explaining subclassing is even harder. PaCs bring significant simplifications in both areas. I don’t like the idea of having something that superficially looks simple (class literals as syntactic sugar for constructors-as-classes), but has the same old complexity under the hood.
I bet that in the coming year more new people are going to learn JavaScript than everyone who knows it now. We have to plan for former group, not for the latter.
=== Instantiation versus initialization ===
Note that your two lines work exactly the same with the following code (which is ES5 JavaScript):
function Person(name) { this.name = name; } Person.prototype.describe = function() { return "Person called "+this.name; };
I do agree that it is a bit strange that the constructor is just another method. In a way, PaCs separate two concerns (that are muddled with constructor functions – see subclassing):