Protalk

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 (c) 2007-2008 Adrian Kuhn. Protalk is provided as it is, use it at your own risk.


How does PROTALK work?

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

Change the Class of an Object

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)

A Class of its Own

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

Everything is a Class

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...

Literals are not Constants

To be continued...

Any object is a Compiled Method

To be continued...


Other work