In a class-based language (like JavaLanguage
), 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.
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
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.
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.)
Examples for PrototypeBasedProgramming
, Flash ActionScript
, InformLanguage (Really !!??)
, the MOO language of LambdaMoo
, kevo, WheatLanguage
, and GlyphicScript?
(see also the list on PrototypeBasedLanguage
I think RubyLanguage fits this as well. Someone knowledgeable please decide and RefactorMe.
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
in the definition of f in the super-object (forget the ^ and it could be Smalltalk). Whereas
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?
may help bringing some of this into the mainstream perhaps.
, 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
, ISBN 1565923928
). -- SteveWainstead
et al wrote an interesting paper about how to organize an object-oriented program without classes (using SelfLanguage
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://lieber.www.media.mit.edu/people/lieber/Lieberary/OOP/OOP.html#Delegation
- is moving away from a prototype model:
(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.
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).
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
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
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 MetaClasses, 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 MetaClasses, 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 MetaClasses will force the program to reinvent them and call 'em factories.
- 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?
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!
[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]
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/
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.
'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).
, 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
, halfway down the page. --MarijnHaverbeke?
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
CategoryPolymorphism CategoryPrototypeProgramming ProgrammingParadigm