Prototype prototype. (Was: Re: Re: How about... something completely different?(Re: Re: On traits composition))

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Prototype prototype. (Was: Re: Re: How about... something completely different?(Re: Re: On traits composition))

Igor Stasenko
I just prototyped own Prototypes hackish implementation. :)

Comparing to Russel's implementation [1] ,
there is no pressure of inheriting from a Behavior.
A clean prototype inherits from nothing , but gains a behavior from its class.

The prototype reference is stateless object, carrying no state.
Instead, its class reference points to a 'stateful prototype', which holding
'prototype methodDict format' ivars to make VM happy
as well as slots and couple of other things.

The slots can be added on the fly , without using #become: ,
since a slot placeholder is a method in method dictionary! :)
(this btw, makes prototype slots access speed nearly same as for any
other smalltalk object using accessor).

All things, like replacing a prototype's prototype slot is working.

To communicate with 'stateful prototype' i'm using the hack, provided
by VM - by sending a #class message
to receiver, which bypassing a standard lookup procedure. :)

Traits naturally fit well with prototypes, and i using them from the
very starting.
An initial prototype object constructed using traits to fill initial behavior:

initialize
        | proto |
        methodDict := MethodDictionary new.
        binding := nil->self.
        format := 2. "Object format"
        prototype := nil.
       
        "Add method from TBasicPrototype trait"
       
        TBasicPrototype methodDict do: [:method |
                self addMethod: (method clone methodClass: self)
                ].
        statelessOp := self primNew.
       
        "Add the TTraitInheritable trait"
        proto := statelessOp new.
        TTraitInheritable methodDict do: [:method |
                proto addMethod: method
                ].
        ^ proto new
       
the resulting prototype is more-or-less ready for use, having
TBasicPrototype -> TTraitInheritable prototype as delegates.

You can start experimenting with it:

| proto |
proto := PrototypeFactory new.
proto inheritTrait: TPrintable.
proto prototype "print it"

 a Prototype( *prototype: a Prototype #traits: a Set(TPrintable) (a
Prototype>>#fullPrintString "a CompiledMethod(3976)") (a
Prototype>>#isKindOf: "a CompiledMethod(3228)") (a
Prototype>>#printOn: "a CompiledMethod(3398)") (a
Prototype>>#printString "a CompiledMethod(122)") (a
Prototype>>#printStringLimitedTo: "a CompiledMethod(367)") )

next, make a Point .

proto importTrait: TPoint.
point := proto new initialize.
point x: 50.
point "print it"

a Prototype( *prototype: a Prototype #x: 50 #y: 0 )

Take a closer look, at 'magic' in
TTraitInheritable>>traits
and
TPoint>>initialize
and why it is possible (PrototypeFactory>>installSlot:value:)

Of course, implementation is not complete. Just a proof of concept :)
Have fun :)

[1] http://russell-allen.com/squeak/prototypes/

--
Best regards,
Igor Stasenko AKA sig.



WeirdExperiment.st (19K) Download Attachment