I think its important to make a distinction between chained and unchained prototypes...
By unchained prototypes I mean those that directly extend Object.prototype (note that that every built-in prototype specified by ES5 is unchained). Unchained prototypes are gorgeous - one instance defining the properties of many. And it's really not that hard...once you understand the difference between Constructor.prototype and instance.__proto__ (or its symbolic successor) you're all set. The concept itself is very simple - a dynamic archetype to be shared by all my instances: my prototype changes, my instances know about it. I would not want to hide such a smart, simple concept behind the more complex and (in this scenario) less meaningful concept of class. By chaining prototypes together we can mimic classical inheritance: objA -> objA.prototype -> objB.prototype -> Object.prototype. As everyone knows prototype-chaining is non-trivial (though made easier by es5's Object.create) and this is the rationale for a class literal in es6: let the language absorb the complexity and let the engines make it faster. This would be fine and good if classical inheritance were a good fit for JavaScript, but I don't think it is: a) The syntax may be fixable but the logic isn't. Inheritance hierarchies are gnarly. - Nine times out of ten it's a re-use technique masquerading as a classification of types. Yes a shark is a fish (thanks @jb_briaud) and if you ever need a fish and a shark in your JavaScript then classical inheritance is for you. However if its re-use you want (and it almost always is) then implementation inheritance is tedious at best, a death-march at worst, because sooner or later the hierarchy becomes arbitrary and self defeating. Single-root trees are good for representing ancestry, I can attest that they are not good for defining re-use. - Even when the intention is to model relationships between types the process is awkward. Most types have multiple characteristics but classical JavaScript allows for only one parent. Moreover classical hierarchies must be implemented top-down - a superclass must be created before it can be extended - yet classes closer to the root are by nature more generic and abstract and are more easily defined *after* we have more knowledge of their concrete classes subclasses. Hierarchy definition is by necessity iterative which does not play well with an existing code base. b) JavaScript already has cleaner, lightweight, more flexible options: - Mixins allow objects to borrow from an unlimited number of other objects regardless of lineage, while still allowing for organization of functions by type. Mixins are way more flexible than inheritance chains - we can buy behavior types on demand with zero impact on the larger model. Prototypes facilitate Mixins, since a mixin is normally applied to an unchained prototype, another reason why new developers should continue to understand prototypes - 'class' is not a helpful concept where Mixins are concerned. - Delegation (call/apply) lets you grab any function whenever you need it. Classical Inheritance is necessary when your language constrains function usage by type hierarchy (Java, C++). JavaScript doesn't do this and doesn't need it. - The module pattern allows a chunk of data and functionality to be parceled into an object which can be used anywhere without compromising the integrity of the module's code. This ability to package up mini-eco-systems frees the developer from constraints of context that would occur if the same logic were defined as part of a class. c) How does the class concept square (no pun) with objects like Math, which is not a constructor and \therefore will not, I assume be considered a class? Is Math.pow a const now? If so how will that work when Math is not a class? If not that seems like an inconsistency. tl;dr.... Unchained prototypes: Invaluable concept; would be obfuscated by class syntax. Chained prototypes: Class literals might fix the syntax but the not the concept. JavaScript has better, easier tools already. ----------- I don't buy the argument (advanced by some in this discussion group) that as long as nothing is removed from the language, new features can't hurt. JavaScript has fewer keywords and a more lightweight syntax than almost any other mainstream language. For many of us that is hugely appealing and paradoxically it makes JavaScript enormously expressive. C++ syntax has everything but the kitchen sink (maybe that too) but as a language I suspect it bores most of use to sobs. Less is more. Earlier in this thread, Brendan said "I claim we can do little to control the outcome in terms of adoption...the classical OOP patterning in many devs' brains, count more than our exhortations." That's sad because I think many ex-classical programmers (myself included) grew tired of implementation inheritance as the dominant paradigm and gravitated to JavaScript (and also functional languages) as a refuge from the stodgy tyranny of bloated hierarchies. The classical OOP ship may have sailed, but its taking on water. I'm not convinced that "users don't care and they want to write new C and have it just work" - I think that does a disservice to our community. JavaScript is on the upward path, Java on the down. We're fostering a generation of converts from classical OOP to something more elegant, agile and useful. It would be a shame to throw in the towel now. Angus On Wed, Jun 29, 2011 at 3:08 PM, Brendan Eich <bren...@mozilla.com> wrote: > On Jun 29, 2011, at 2:24 PM, Axel Rauschmayer wrote: > > >> That's all neat in a kind of desugaring ftw, nerdcore way, but tl;dr -- > users don't care and they want to write new C and have it just work (mostly; > granted some crack the code, for a few good and bad purposes). > > > > Note that I am arguing from the perspective of a language that only has > PaCs, versus a language that only has constructor functions. If you don’t, > then we don’t disagree. > > That was not clear, because we keep coming back to JS as it is. That's > where I want to land, so arguing about what-if's and might-have-been's is > not my cup of tea. > > > > You argue that constructor functions are more intuitive at the user level > (to *all* people) and that PaCs wouldn’t “just work” > > I never wrote anything like either of those things, certainly not "to *all* > people". Indeed I was the one pointing out that your universals did not > apply to all people. > > Last concrete disagreement we had was over new C() vs. C() in the current > language being notably different from new C() vs. C.constructor() in the > alternate-reality language with prototypes as classes. > > /be > _______________________________________________ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss