simple object model

Jecel Assumpcao Jr jecel at merlintec.com
Fri Apr 6 00:50:41 UTC 2001


On Thursday 05 April 2001 10:57, Uladzimir Liashkevich wrote:
> > [new object with slots filled from arguments]
>
> Yes. It is actually what you should do in this case. It looks not so
> easy, so I don't like that approach.

It is important to find out just how much this kind of thing is needed. 
A language should make common things easy, rare things possible. Of 
course, there is a great danger of circular reasoning here: something 
very useful could be rarely used because our current languages make it 
so hard (or inefficient) to do.

> In my opinion, mirrors should not be used in ordinary applications.

Very true.

> In addition, this solution doesn't look acceptable for frequent use.
> It would be nice to have a construction equivalent to (| x = aX. y =
> aY |) that is evaluated at run-time on every occurance.

Where would this be used? Note that quoting conventions can become very 
complex for the kind of expression you want. Some languages have 
something similar for creating function creating functions. 

I just noticed that since the assignment primitive returns the modified 
object, the non constant slot, non cloning version of the example could 
have been written more simply as

             ... ^ ( (| x. y |) x: sX) y: sY

> So I would suggest to preserve the idea of using _map_ in each object
> transparently.

Well, I did mention a not so transparent map-like variation:

  ((x : y :) 3 4)

The embedded list with the two indirect slots works as both a map and 
as an anonymous parent (by the way, except for assignable parents and 
directed resends do we actually gain anything by making parents visible 
at the base level?). If you clone this, you will only take up three 
words. And the shared list at the begining of this object and its clone 
would be a sort of type information.

> For example, you may consider introducing implicit parent for all
> objects. I.e. even empty object () would have a parent 'traits
> basicBehavior'.

In Self the primitive interface is much cleaner than in Smalltalk, 
since they look like normal message sends and use the normal send 
bytecodes. But then things become a little strange - how do you look 
them up? They have to be found in some hidden table deep inside the 
virtual machine or else you couldn't send primitive messages to objects 
like ().

> Also I think that syntax (x 3. y 4) is more consistent.
> Because code constructions use dot as a separator too.

I wasn't thinking of having this in the lowest level of code, but use 
an array of arrays instead:

   ((stuff 1) (stuff 2) (last stuff))

The user would not have to write it like this, of course (this is how 
it works in Logo, for example).

> > My idea is that the arguments would be underlined, but that is hard
> > to show using ASCII in this email.
>
> What notation should be produced by parser - Polish or direct?

Direct (infix). It really doesn't make a difference for a compiler, but 
for an interpreter it would seem that you have to go with Polish or 
RPN. Except I have a very nice interpreter I designed in 1983 which 
sends the message *before* evaluating the arguments, so it can execute 
infix code very well. The advantage is that by the time the value of an 
argument has been calculated, the place where it will ultimately go has 
already been created and so there is no need to save it on a local 
stack only to later copy it to another stack.

I have recently found out that the last Lisp machine at LMI worked 
exactly like this (it had an OPEN instruction and a separate CALL 
instruction) so I can borrow their ideas in my hardware design. So not 
only would my "machine code" (the arrays - thank you for your vote :-) 
be very readable, but my "microcode" would as well.

> How are you planning to handle 'resend.' and '_parent_.'
> constructions?

At the low level these things can be handled by primitives since they 
are infrequent enough.

                            resend.copySize: n

could be translated into

                           _PerformResend: 'copySize:' With: n

though this particular primitive is missing in Self 4.1.2 - you can 
only do non-directed resends of unary messages. Actually, you can do 
directed resends using the '_Perform:DelegatingTo:With:' type 
primitives, as far as I can tell.

Thanks for your comments,
-- Jecel



More information about the Self-interest mailing list