In a class-based language (like JavaLanguage or SmalltalkLanguage), every object is an instance of a class. An object contains its own data (instance variables), but its class holds its behaviour (methods). To make a new object, you ask a class to "instantiate" itself. In a prototype-based language, an object can contain both data and behaviour. It's a self-contained thing. To make a new object, you just call the "copy" method on an existing object. ''AnswerMe: The answer to this might be obvious to Smalltalkers, but anyway: can Smalltalk plausibly be extended to give prototype-based inheritance as well as class-based inheritance? If so, I will learn Smalltalk starting the minute I read the answer! (Oh, OK, I'm learning Smalltalk anyway, but I'm not sure yet that I like it as much as IoLanguage.) -- JasonGrossman'' To (sort of) answer my own question: yes, there are several ways of using Smalltalk in a prototype-based. But as far as I can find out, they're all clunky ... EXCEPT for a new dialect of Smalltalk called PragmaticSmalltalk. -- JasonGrossman There are a bunch of psychological reasons why I think prototypes work better, but here are some more practical reasons: * The language rules can be simpler. For example, you don't run into any issues like "Is a class an object?" and "If a class is an object, what class is it an instance of?" (In Java, a class is sorta-kinda an object, but not really a very useful one. In Smalltalk, a class is a proper object, but because of that, there's a whole silly complex metaclass system. In Self, the issue just doesn't come up - you get all of Smalltalk's power, without the extra complexity.) * You can give specialized behaviour to individual objects. This has all sorts of uses, but it's particularly useful when debugging. I've got an object on the screen that isn't behaving properly, so I ask to see that object's code, and override a method or two (on just that one particular object) to help me debug it. * A few platypi (like the SingletonPattern) completely disappear. If you want there to be only one of a particular kind of object, then... only make one of them. If you don't want it to be able to be copied, then don't give it a "copy" method. * You start to think of a bunch of new kinds of objects that you couldn't really think of in a class-based language. For example, I'm particularly fond of Self's namespace objects. (Self has a really nice namespace system, without any special namespace-related rules whatsoever in the language - it's all just ordinary objects. Nesting namespaces is done using ordinary inheritance.) -- AdamSpitz ''See ClassesPrototypesComparison'' ---- Examples for PrototypeBasedProgramming include JavaScript, Flash ActionScript (1.0), SelfLanguage, NewtonScript, IoLanguage, InformLanguage ''(Really !!??)'', the MOO language of LambdaMoo, RebolLanguage, kevo, WheatLanguage, and GlyphicScript (see also the list on PrototypeBasedLanguage). ''I think RubyLanguage fits this as well. Someone knowledgeable please decide and RefactorMe.'' - RubyLanguage is not Prototypes based. It has a simple but muddled class based architecture which allows some prototypes like capabilities e.g. mixins, method removal etc. Newbies often get confused about the "Class is a class and Object is a class too and Class is an instance of Object" in Ruby due to this reason. ''Don't forget Lua!'' Note that this usage of the word "prototype" does not mean "a small program build to validate requirements or designs". However, PrototypeBasedLanguage''''''s are quite effective for building prototypes :-) ---- What happens in a prototype language in the following case: object A delegates to object B; object A calls a method f on itself, which gets delegated to B; then B calls a method g on itself. If A also has a version of g, does that version get called (like in a traditional class-based language)? If so, that means that there always is an implicit "real" object beneath the curtain? -- StephanHouben In the one prototype object language I've used in anger commercially, called Vision, the normal case is indeed that A's version of g is called, using ^self g in the definition of f in the super-object (forget the ^ and it could be Smalltalk). Whereas ^here g ^current g both explicitly call g as defined in B, the super-object. But whereas ^here keeps the original sub-object A in view for future method calls, ^current causes A to be forgotten and the computation to proceed simply as a message send to B. Easy isn't it? Despite this necessary complication, the idioms of prototype-based programming have a lot going for them. Even JavaScript may help bringing some of this into the mainstream perhaps. -- RichardDrake In LambdaMoo, a method ("verb") call which occurs on the delegate/superclass ("parent") object B will start looking for the method from A: if the method is defined on A as well as B, the version on A will get called [unless it's not executable or a few other special cases exist]. The version on A can, of course, defer or call the versions further up the inheritance tree. ---- '''Is it Cloning or Dynamic Look-up?''' There is a good clear explanation of prototype-based inheritance in TheRhinoBook (O'Reilly's ''JavaScript: The Definitive Guide'', ISBN:1565923928). -- SteveWainstead ''I find the 3rd edition a bit fuzzy on the use of the term. It seems early JavaScript simply cloned other objects to "inherit" their properties and methods. After the cloning, there was no longer any language-enforced relationship between them. It is mitosis: divide and run. However, it seems newer versions of JS have added a "prototype" property that facilitates a "look-up" to another object that acts as the parent if the item is not found in current object. This is no longer clone-based, but rather a dynamic form of "regular" inheritance. Thus, perhaps "cloning" is different from prototypes. I see 3 types of inheritance: 1. cloning, 2. run-time look-up of parent(s), and 3. compile-time look-up of parent(s).'' ---- DavidUngar et al wrote an interesting paper about how to organize an object-oriented program without classes (using SelfLanguage): http://research.sun.com/self/papers/organizing-programs.html -- KrisJohnson ---- If you would like to read the original paper where I first introduced the idea of prototypes in object-oriented systems, from Oopsla 86, Using Prototypical Objects to Implement Shared Behavior in Object-Oriented Systems: http://web.media.mit.edu/~lieber/Lieberary/OOP/OOP.html#Delegation -- HenryLieberman (Feb, 2002) ---- Interesting (or perhaps frightening) to note is that the one prototype language in common usage - JavaScript - is moving away from a prototype model: http://www.mozilla.org/js/language/js20/index.html (Randy, the old link was dead. I hope you don't mind.) -- RandyBrown ---- ''It is VERY frightening to me, for the simple reason that the proposed change seems largely motivated by that author's personal preference for classes. It blows my mind that he lists ease of education as a reason to add classes - in fact, I've found 100% of the time that people find prototypes easier to understand because you don't have all the Platonic baggage of "this object is a member of an abstract class of objects". It's much more concrete.'' ''JavaScript with classes is not JavaScript.'' Yes, they are going to ruin JavaScript. I guess the motivation is to make Ecmascript 2.0 very similar to JScript.NET, which, due to the restraints imposed by the CTS, has classes, visibility modifiers and more (aka the silly include statement which absolutely breaks compatibility of JScript.NET IO and IO in Jscript). ''Actually, the "classes" look hackish, really. They are functions that refer to ''this''. That's it.'' eg. SomePrototype = {something:null, something_else:null, some_method:function() { blah() }}; becomes function SomeClass() {this.something = null; this.something_else = null;} function some_method() {with(this) blah();} ---- Prototype-based programming is common in the construction of InteractiveFiction games and MultiUserDungeon(s). See LambdaMoo, for example. ---- I've become excited about PrototypeBasedProgramming, mostly from epiphanies from reading http://www.crockford.com and from using the JavaScript language. For those folks familiar with C/C++ and low-level Microsoft COM (ComponentObjectModel), here's an implementation-oriented attempt at explaining the prototype concept... I've always thought of C++ primarily as taking C and adding syntactic sugar to get you to vtables (virtual method lookup tables). I blame Microsoft and early COM and the old world where C++ compilers were just preprocessors for C for this twisted thinking. Early COM used to provide nasty C macros that helped you create your own vtable function pointer arrays so that you could pretend to be C++ from C. Now, imagine: replace those vtable function pointer arrays with nice, memory-hoggish String-keyed hashtables (the Strings are the method names). And, allow chaining of those hashtables. Whenever the language engine needs to lookup a method to invoke on an object, the language engine consults those hashtable chains (which are also called prototypes). Also, whenever you need to do a property get or property lookup on an object, the language uses those same String-keyed hashtable chains. Whenever the language needs to do a property set or add a new method, it doesn't touch the hashtable chains, but sets the object's slot only. Finally, those hashtables are also just objects, too. So, put those hashtable chains under control of the language as just first class objects, and ta-dah - you have prototype based language implementation. It's vtables under your control again. And, very powerful. -- SteveYen ---- Concerning the points brought up by AdamSpitz: * Is it ever necessary to deal with a class as an object? For instance, in CsharpLanguage (my current language of choice for financial rather than aesthetic reasons), every class automatically inherits from the Object class. It provides a mechanism for instance methods to exist for every class, everywhere (since the compiler forces a non-derived class to inherit from Object) although, admittedly, you can't actually make any changes to the Object class. Additionally, you can use reflection (as in Java) to retrieve information about class names, methods, properties, etc. I'm curious - why exactly would you ''need'' a 'Class' object? Or is it simply an artifact of the language? ''Yes, it is necessary, consider that the factory pattern is a hack to simulate a MetaClass for its type. This is all part of the MetaObjectProtocol, but having MetaClass''''''es, removes the need for patterns like Singleton, and Factory and language elements like new. New in reality is a method of the class object for it's type, i.e. ICustomer aCustomer = Customer.New();. Static methods are also a hack to sort of simulate class methods, but if csharp had real MetaClass''''''es, then you could do things like inherit and/or override constuctors, since they wouldn't be special methods anymore, they'd just be regular methods of the metaclass for that type. Any language without MetaClass''''''es will force the program to reinvent them and call 'em factories.'' Interesting - so a MetaClass allows you to customize the behavior of how objects are instantiated. It also allows you to maintain state information about instantiated objects in an intelligent location - the MetaClass object itself - rather than hiding in static fields. Rather than hacking out factories, singletons, etc. you can simply provide appropriate methods that provide whatever functionality you need... in the MetaClass. (For instance, as mentioned above, if you want a singleton, don't provide a Copy() method.) I like it! * Adding specialized behavior to objects - although it's fun (and I've actually done it before when doing mental gyrations in JavaScript, long before I realized the value of refactoring), is it a particularly elegant solution? I see the value of implementing it for debugging, but in production code? Maybe it's just a gut reaction to trampolines, but sounds like a good way to shoot yourself in the foot (YoullShootYourEyeOut). I'm not complaining - I'm just curious about serious examples (aside from debugging, where the utility seems obvious - it's easier than creating a subclass with special features), some sort of example that doesn't scream 'refactor me!' [Just found an example answer to my own question. In ASP.NET, you can add 'server controls' (programmatic entities which display HTML - typically HTML elements such as textboxes, radio buttons, etc - then process the data posted to the server to provide 'onchange'-style events and updated data in a server-side application) to other controls. If a server-side event (such as a textbox's textChanged event) occurs for an ordinary control, you can provide an event listener to do something when that event is triggered. Now, in the case I mentioned, where (for example) I have a Table object (displays a simple HTML table) that contains a bunch of textbox objects, there is a mechanism to 'bubble' events from those textboxes up to the Table control. Easy enough. However, the only way to bubble an event is to actually call a raiseBubbleEvent method in the textBox's code - you can't switch it on and off. As such, I need to create my own special class that derives from textBox, override the method, and make sure this "bubbleTextBox" object (or whatever) is instead added into my Table. Were I able to add specialized behavior as discussed above, I could just override the onTextChanged method of each textbox added to the table. (Say - is this safely OOP? In a way, you're creating self-modifying code...) There's no need to create a derived class that will ''never be reused''. It sounds like any circumstance in which you need to make a very minor tweak to a class in a standardized library - the sort of simple tweak that makes it overkill to create a new derived class - is a good argument for PrototypeBasedProgramming.] [FYI - this 'specialized behavior' is known as the DecoratorPattern] * As for the disappearance of the SingletonPattern, halleluiah! The namespace object mechanism sounds interesting as well. Despite my concerns, I think it's time to invest a little time learning about Self... [Or IoLanguage. -- JasonGrossman] -- JosephRiesen There is no 'safely OOP' standard for what is OK and what is not. OOP is still developing, and the Java/C++ forms of it are far from the state of the art. --MarijnHaverbeke ---- Io's sample page [http://www.iolanguage.com/about/SampleCode/] is a fantastic advert for prototype-based programming. But it left me wondering why prototype-based languages haven't taken off? Why did the mainstream adopt class-based languages instead? Why are JavaScript and SelfLanguage the two biggest exemplars of a programming paradigm that manages to combine expressiveness with elegance? Is there some hidden flaw in this approach that I'm missing? ''I think it's probably because it's relatively new (roughly 1980 instead of 1970) and because it's unconventional, given that most programmers learn OOP from C++ or Java. It also implies a lot of dynamism, which is anathema to the mainstream software development model. I think the next dynamic language to take off (after Ruby and Python) will probably be prototypical. Classes just don't buy you much in a dynamic language.'' Given that it's taken class-based OO languages just over 30 years to get into the mainstream I think we can confidently predict that PrototypeBasedLanguage''''''s will be all the rage in 2010. ''Uh, JavaScript is widely used and it's certainly a PrototypeBasedLanguage. Of course, many programmers in JavaScript couldn't give a hoot about the difference between class-based and PrototypeBasedLanguage''''''s, and it's a strawman argument anyway. See ClassesPrototypesComparison.'' Apparently, JavaScript's prototypes are considered a deficiency, because the draft of the latest EcmaScript standard has full classes. Fools! ''Instead of, or in addition to prototypes? The two concepts really ought to be unified...'' I think EcmaScript's classes are likely implemented on top of prototype-based stuff. That's certainly the case in Flash's Actionscript. In Flash MX (Flash 6), Actionscript is pure prototype-based. In Actionscript 2, introduced with Flash MX 2004 (the Flash 7 Player, just to confuse things), MacroMedia added classes and nearly full EcmaScript compatibility. The class stuff compiles to the prototype-based OO idioms that people used manually under Flash MX which is why stuff composed in Flash MX 2004 will still run on Flash 6 and possibly even Flash 5 players. I suppose this is some sort of proof that prototype-based languages subsume class-based. OTOH I think it's very interesting that MacroMedia thought this change was necessary - I'm not sure if their reasons where to achieve EcmaScript compatibility for some marketing reason or because they thought the prototype-based approach was too scary. I got myself into trouble a few times because it is possible to write subtle bugs by minor syntax accident (eg: a "class" which will only allow one instance). -- AndyDent ---- I write a ton of JavaScript and I rarely use the prototypes or create my own classes, because I find the class syntax (and especially the broken goddamn scoping) to be enormously annoying. That said, it sometimes is really useful, like when you're fixing the useless built in String class. I'd rather see namespaces than real classes in JavaScript, though. Current scoping rules are such that you can't even safely emulate namespaces with objects. At least give me a way to specify file scope! -- ChrisMellon (Getting off topic, but closures can be used to fake file scope. See http://eloquentjavascript.net/chapter9.html , halfway down the page. --MarijnHaverbeke) ---- The OpenLaszlo programming language elegantly solves JavaScript's annoying class syntax and scoping problems, with a simple XML class declaration and object instantiation syntax. Laszlo programs are valid XML documents, containing JavaScript code in method bodies, and JavaScript expressions in attributes. You can customize any object with its own methods, event handlers and attributes. Furthermore, Laszlo's class declaration and object instantiation syntax supports InstanceFirstDevelopment, as described in Oliver Steel's article on Classes and Prototypes at http://osteele.com/archives/2004/03/classes-and-prototypes -- DonHopkins ---- CategoryPolymorphism CategoryPrototypeProgramming ProgrammingParadigm