In a class-based language (like Java Language or Smalltalk Language), 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.
Answer Me: 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 Io Language.) -- Jason Grossman
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 Pragmatic Smalltalk. -- Jason Grossman
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 Singleton Pattern) 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.)
-- Adam Spitz
Examples for Prototype Based Programming include Java Script, Flash Action Script (1.0), Self Language, Newton Script, Io Language, Inform Language (Really !!??), the MOO language of Lambda Moo, Rebol Language, kevo, Wheat Language, and Glyphic Script (see also the list on Prototype Based Language).
I think Ruby Language fits this as well. Someone knowledgeable please decide and Refactor Me. - Ruby Language 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, Prototype Based Languages 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? -- Stephan Houben
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 Java Script may help bringing some of this into the mainstream perhaps.
In Lambda Moo, 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 The Rhino Book (O'Reilly's Java Script: The Definitive Guide, ISBN:1565923928). -- Steve Wainstead
I find the 3rd edition a bit fuzzy on the use of the term. It seems early Java Script 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).
David Ungar et al wrote an interesting paper about how to organize an object-oriented program without classes (using Self Language): research.sun.com -- Kris Johnson
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: web.media.mit.edu
-- Henry Lieberman (Feb, 2002)
Interesting (or perhaps frightening) to note is that the one prototype language in common usage - Java Script - is moving away from a prototype model: www.mozilla.org (Randy, the old link was dead. I hope you don't mind.) -- Randy Brown
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.
Java Script with classes is not Java Script.
Yes, they are going to ruin Java Script.
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 Interactive Fiction games and Multi User Dungeon(s). See Lambda Moo, for example.
I've become excited about Prototype Based Programming, mostly from epiphanies from reading www.crockford.com and from using the Java Script language. For those folks familiar with C/C++ and low-level Microsoft COM (Component Object Model), 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. -- Steve Yen
Concerning the points brought up by Adam Spitz:
Is it ever necessary to deal with a class as an object? For instance, in Csharp Language (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 Meta Class for its type. This is all part of the Meta Object Protocol, but having Meta Classes, 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 Meta Classes, 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 Meta Classes will force the program to reinvent them and call 'em factories.
Interesting - so a Meta Class 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 Meta Class 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 Meta Class. (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 Java Script, 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 (Youll Shoot Your Eye Out). 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 Prototype Based Programming.]
[FYI - this 'specialized behavior' is known as the Decorator Pattern]
As for the disappearance of the Singleton Pattern, 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 Io Language. -- Jason Grossman]
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. --Marijn Haverbeke
Io's sample page http://www.iolanguage.com/about/SampleCode/ www.iolanguage.com 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 Java Script and Self Language 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 Prototype Based Languages will be all the rage in 2010.
Uh, Java Script is widely used and it's certainly a Prototype Based Language. Of course, many programmers in Java Script couldn't give a hoot about the difference between class-based and Prototype Based Languages, and it's a strawman argument anyway. See Classes Prototypes Comparison.
Apparently, Java Script's prototypes are considered a deficiency, because the draft of the latest Ecma Script standard has full classes. Fools!
Instead of, or in addition to prototypes? The two concepts really ought to be unified...
I think Ecma Script'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), Macro Media added classes and nearly full Ecma Script 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 Macro Media thought this change was necessary - I'm not sure if their reasons where to achieve Ecma Script 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).
-- Andy Dent
I write a ton of Java Script 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 Java Script, 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! -- Chris Mellon
(Getting off topic, but closures can be used to fake file scope. See eloquentjavascript.net , halfway down the page. --Marijn Haverbeke)
The Open Laszlo programming language elegantly solves Java Script's annoying class syntax and scoping problems, with a simple XML class declaration and object instantiation syntax. Laszlo programs are valid XML documents, containing Java Script code in method bodies, and Java Script 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 Instance First Development, as described in Oliver Steel's article on Classes and Prototypes at osteele.com
-- Don Hopkins
See original on c2.com