PROTALK extends Smalltalk with prototype-based inheritance, ie delegation.
PROTALK turns Smalltalk object into real prototypes, without any change to the virtual machine. Protalk objects share the same object space with Smalltalk objects—actually, they are pure Smalltalk objects: an instance of a Protalk prototype is no different than an instance of a Smalltalk class. PROTALK uses the same inheritance and the same method lookup as Smalltalk.
Download: http://www.squeaksource.com/Prototype.html
Acknowledgments: Protalk was born on a boat trip at ESUG 2007 during a discussion with Travis Griggs. Protalk was originally implemented for Visualworks Smalltalk, and has recently been ported to Squeak with the kind help of Matthieu Suen.
Copyright © 2007-2008 Adrian Kuhn. Protalk is provided as it is, use it at your own risk.
Protalk objects are pure Smalltalk objects, with one small difference: each Protalk object is its own class. Protalk is pure Smalltalk, it relies on two features that had been hiding in plain sight since Smalltalk-80
We all know how to get the class of an object
(3@4) class ⇒ Point
What about setting the class of an object, does that work?
(3@4) class: Assocation
Yes it works, but you must write it as follows
(3@4) primitiveChangeClassTo: Association basicNew ⇒ 3->4
This changes the class of the receiver into the class of the argument, given that (R = receiver, A = argument)
Now, as we know how to can change the class of an object, we can create an object that is its own class.
oroboros := Class new. oroboros superclass: Class. oroboros methodDictionary: MethodDictionery new. oroboros setFormat: Class format. oroboros primitiveChangeClassTo: oroboros basicNew
oroboros class = oroboros ⇒ true
We all know, everything is an object and everything has a class. But did you know that everything is (possibly) a class? Any object can create instances of itself, given that
If your object satisfies these constraints, the VM accepts it as a class and you can use your object to create instances of itself.
Let’s do that. First we have to create a new class Thing
that inherits from object, ie instances of Thing
are just normal objects. Then we will use an instance of Thing
to create an instance of an instance of Thing
.
Create a new class Thing
with three instance variables
Object subclass: #Thing instanceVariableNames: 'delegate methods format' classVariableNames: '' poolDictionaries: '' category: 'Sandbox'
Implement an initializer and a method new2
that calls primitive 70.
Thing >> initialize delegate := Object. methods := MethodDictionary new. format := superthing format.
Thing >> newToo <primitive: 70>;
Now, execute in a workspace:
object := Thing new. abomination := object newToo.
abomination class ⇒ object abomination class class ⇒ Thing
Hence, instead of the usual two levels
object --isa--> Thing
we have now three level of instantiation
abomination --isa--> object --isa--> Thing
In the same way we can go to an unlimited number of instantiation levels. Combining this with the oroboros example above, we can create a prototype-based subspace within the class-based object space of a Smalltalk image.
To be continued...
To be continued...
To be continued...