cloning/invocation
Jecel Assumpcao Jr
jecel at merlintec.com
Wed Aug 28 21:20:03 UTC 2002
On Tuesday 27 August 2002 18:23, Marcel Weiher wrote:
> Not if it can be hidden, just like you hide *not* making the copy. I
> wonde why you see one as changing semantics, and its inverse as not
> changing the semantics.
We are talking about an object with a mutable part (prototype for
temporary variables and arguments) and an immutable part (bytecode,
sources, literals, etc). Either making a full copy or a partial copy
that shares the immutable part will give you results that behave in the
exactly the same way.
Not making a copy at all will give you a different behavior. In
particular:
> > Without a copy, two
> > different invocations of a method would share temporary variables
> > and arguments.
>
> Oh, please! Every C function, Pascal procedure/function, Smalltalk
> method, etc. manages to do this without making a copy of the method,
> simply by externalizing the mutable state.
You have to properly initialize the stack frame. How do you do that? By
copying some values from the code or some other area.
int foo ( char c ) {
int count = 0; max = 99;
while ( count < max ) { .... }
}
Some initial code in "foo" must copy 0 and 99 to the right places on the
stack.
> > With a copy, each one has a separate state.
>
> You don't need a copy for that, just a proper lookup algorithm.
Two different invocations of "foo" will allocate different memory
addresses for "count" and "max", and each one will copy 0 and 99 to
those memory addresses. We can make them not copy by doing
static count = 0; max = 99;
but now the two invocations will step on each other's toes.
> > Of course, the declarative "invoke with arguments" will almost
> > certainly
> > have implicitly in its semantics some form of copying.
>
> No, it is creating a new method context, and leaving the method
> alone. Nothing is being copied.
>
> > I am just stating explicitly that this is what is happening.
>
> Well, then you are explicitly wrong about this ;-)
I hope that the C example will make what I am trying to say clearer.
> Yes. I am fully behind the importance of interactive object
> construction, but I am convinced it doesn't go far enough. In fact,
> I want to make it even better than it is.
So do I. In the message that started this thread I was proposing making
changes to Self that I thought might make it better.
> Simple from an implementation point of view (all handled via one
> mechanism). But I disagree that this is simple for the user. Before
> I give my reasoning, let me first reiterate that I agree that
> constructing objects (once) is simple for users, the question is
> where to go from there. Let me also try to clarify what I mean by
> "simple": reducing the cognitive load for a given construct as much
> as possible.
Ok.
> With copying and modifications, you have to remember and be aware of
> the history of an object to know what it is like now. This makes the
> whole thing more complex. Once again, I believe there is a reason we
> *write* method invocation (procedure calls) as:
>
> (1) result := someObject method: arg1 more:arg2.
>
> and not:
>
> (2) method := MethodProtype copy.
> method setArg1: arg1.
> method setArg2: arg2.
> method invoke.
>
> This seems 'obviously' more complex to me.
I would like the system to have both. A base-level programmer would
write (1) while a meta-level programmer could do something like (2).
> However, we do use object instance this way (2). As far as I can
> see, self says that (2) is really the unifying mechanism, but
> provides both syntax and implementation-optimizations to use (1)
> where
> possible/necessary.
You are right. Just like the exact same syntax
obj x
will return a non cloned object if "x" is a data slot but will cause all
the cloning we have been talking about if "x" is a method slot. Two
different semantics for the same syntax. It is an imperfect shortcut,
but nobody seems to have a problem with it.
> My current approach is to say that (1) is the unifying mechanismmm
> and potentially use (2) internally where necessary (though I'd rather
> it were not necessary). Objects, which can be constructed with all
> the fun of self-style, can be turned into parametrized objects (which
> have some class-like characteristics) by turning some of their
> instance variables into parameters. They are then incomplete, and
> know that they're incomplete. The user also knows that and exactly
> how they are incomplete. To be used, a parametrized object must be
> provided with a context that provides the bindings for the
> parameters.
That sounds good. In fact, if you allow lexical scoping you can actually
get by without inheritance as in Beta or E. I am trying to convince a
friend who is designing a language inspired on Tim Budd's Leda to go in
this direction. My own proposal was in a different direction, but that
doesn't mean I consider it better.
> > Compare this with the model
> > presented in the Blue Book (which can also be seen in the
> > Interpreter class in Squeak).
>
> Ahh, but this really is an implementation...
Not necessarily, and that is one reason we are having such a hard time
understanding each other.
> > You will probably tell me that the "normal"
> > Smalltalker doesn't have to learn about stack pointers, method
> > headers, context objects, etc. Then I will say that the normal
> > Selfish programmer doesn't have to know that activation objects are
> > obtained from cloning method objects!
>
> ...whereas you've said that cloning is the "model" you present, and
> that the implementation doesn't actually do this.
Exactly. There are levels upon levels. At the very top level we can
think of a user typing expressions in a workspace and doing "print it".
He can have a model like you described either in Smalltalk or in Self.
If there is a bug, then he will be thrown into the debugger and a lower
level model will be needed to cope with it. That would be the cloning
in Self and the Blue Book in Smalltalk.
The real implementation can use an even lower level model which can be
very different from the previous one. It isn't in Squeak, but it is in
VisualWorks, StrongTalk or even Smalltalk V. And it is likely to be a
different model in future versions of Squeak (see Anthony Hannan's work
in that direction).
And of course, this implementation might run on a processor that
pretends to execute x86 instructions. And so on. Levels upon levels
until we finally get to the turtles ;-)
> Anyway, this is all too low-level for me anyhow, and method
> invocation is not really what I am talking about. It is making
> dealing with objects more like method-invocation (or function
> evaluation, procedure call) rather than vice versa, making method
> invocations more like munging objects.
As I wrote above, I am big fan of languages which take this idea
seriously even if I didn't adopt it myself.
Cheers,
-- Jecel
More information about the Squeak-dev
mailing list
|