[self-interest] The problem of dynamic inheritance

Jecel Assumpcao Jr jecel at merlintec.com
Tue Jan 13 00:17:46 UTC 2004


On Sunday 11 January 2004 22:04, cyberbaixing wrote:
> Dear All,
>
> I am a newer of SELF. I try to run the a program of dynamic
> inheritance.

It might be a problem with just plain inheritance, not dynamic 
inheritance.

> which is defined as follows:
>
> globals _AddSlotsIfAbsent: (|
>         a =().
>         b =().
>         c =().
>
> |)

Ok, so we now have three objects 'a', 'b' and 'c' which can be accessed 
by sending a message to any object that inherits from 'globals'. So we 
can do something like

    42 a

and get back the first object. But if we try

    () a

then we will get an error saying that the empty object does not 
understand the message 'a'. This will work, however

    (|p*= traits oddball|) a

> a _Define: (|
>         f = ('a' printLine. p:b. f).
>
> |)

Note that this object doesn't understand either the 'p:' nor the 'b' 
messages. And the final 'f' will cause infinite recursion.

> b _Define: (|
>         f = ( 'b' printLine ).
>
> |)

Right.

> c _Define: (|
>         p*<- a.
>         b = b.
>         f = ('c' printLine. resend.f).
>
> |)

Here we have someone who understands both 'p:' and 'b'. Note that the 
reason why the lines

   p*<- a.
   b = b.

worked is that the Self parser initializes slots with expressions that 
are evaluated in the context of the lobby, not the objects in which the 
slots appears. So 'a' and 'b' in these lines were sent to 'lobby' which 
does inherit from 'globals'. This is also the reason why I was able to 
write "traits oddball" in my example above.

> But if I send the message f to slot a, the result is always:
> "Self 14" a f.
> a
> No 'b' slot found in a slots object.

Exactly what I predicted. Didn't you want to send the message to the 
child instead?

   c f

which would give you a result like

   c
   a
   c
   b

Hmm... replacing the parent would avoid the infinite recursion I 
mentioned before. Very tricky :-)

> If I rewrite the slot a without the dynamic inheritance but replace
> with directed resends or undirected resends like this:
>
> a _Define: (|
>         p*<- b.
>         f = ('a' printLine. b. f).
>
> |)

Ok, now 'a' does understand the 'p:' message (which you are no longer 
using)but I don't see how it would understand the 'b' message.

> The result is:
> "Self 14" a f.
> a
> b
> 'b'

I don't understand these results. Are you sure that they correspond to 
the code above?

> Why the resends works but the dynamic inheritance not? Did I make any
> semantic mistakes in slot a's definition?

Hmm... this comment makes me think you actually had something like

    f = ('a' printLine. p.f).

Note the 'p' instead of 'b' and lack of space after the '.'. This would 
give you a result like the one you saw. In any case, try sending 'f' to 
object 'c' instead of 'a' in your first example and see if dynamic 
inheritance doesn't work as you want it to.

> Furthermore, how to understand the meaning of "activation record"?

This is the same thing as "context object" in Smalltalk, if you are 
familiar with that language.

Every time a method is executed, additional information beyond what is 
available in the method object itself must be stored somewhere. That 
somewhere is the activation record. It know the current Program 
Counter, the current value of the stack, who to return to with the 
final result and so on.

> In the above example, which one can be looked as the current
> activation record?

You can see the activation records in the debugger when execution is 
halted due to an error. Each frame in the green "window" is an 
activation record for a different method.

> I  know the slot a is the receiver of the message,
> the method f has a clone. The code of f is running in the context of
> clone.

This clone (plus the extra information I listed) is the activation 
record.

> 'a'printLine prints out the string a, the code p:b.f is to
> change the parent of slot a to slot b. But where is the activation
> record here? Is it same as the activation object?

Self uses the normal machine stack to store information for running 
processes. That stack is divided into frames, also known as activation 
records. But when Self code needs to deal with the stack then these are 
converted into activation objects. So while I have been using the two 
terms as equivalent, they aren't exactly the same thing.

I hope this helps,
-- Jecel



More information about the Self-interest mailing list