simple object model (was: [self-interest] selfing Self)

Uladzimir Liashkevich uml at csp.org.by
Thu Apr 5 14:57:01 UTC 2001


> > When I read about Self, I felt the same as in the case of Smalltalk.
> > Later I discovered the absense of some needful possibilities. One of
> > them is constructing objects on the fly. One cannot write something
> > like this: (| x:Y: = (| :aX. :aY | ^(| x <- aX. y <- aY |) ) |).
> 
> While this doesn't work because slot initializers ("aX" and "aY" in
> this case) are always evaluated in the context of the lobby object, you
> can get the same results with:
> 
>      (| x:Y: = (| :aX. :aY. new |
>             new: (| x. y. parent* = traits clonable |) copy.
>             new x: aX.
>             new y: aY.
>             new)
>      |)

Yes. It is actually what you should do in this case. It looks not so
easy, so I don't like that approach.

> 
> The reason I used 'copy' above is that I am supposing that you don't
> want successive calls to this method to always return the exact same
> object, but just the same kind of object. If that is the case but you
> don't want the new object to be clonable, we could use the '_Clone'
> primitive instead of 'copy' and eliminate 'parent*'.
> 
> If you wanted 'x' and 'y' to be constant slots in the new object (you
> didn't show that in your example) then things do get much more
> complicated. It is still possible to do this using mirrors, however.

In my opinion, mirrors should not be used in ordinary applications. 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.

> 
> But I was indeed trying to make this kind of thing simpler.
> 
> > So
> > now I'm in process of thinking out a more flexible but yet powerful
> > language. By now I have implemented two experimental versions of
> > Self. But I need something different.
> 
> Me too, but more in the spirit of Self than the Self-inspired languages
> of the early 1990s.
> 
> > > Like a simple object model: objects are just flat association lists
> > > (I'll use Lisp notation below) -
> > >
> > >        (x 3 y 4)
> >
> > flat list has an array structure rather than linked list?
> 
> By "flat" I meant compared to this form of association list:
> 
>   ((x 3) (y 4))

There is one problem with that. When you clone the object then the whole
structure should be duplicated, thus clones don't have any shared
attributes. In Self all objects have a special _map_ field that is
shared by all clones and that can be used in determining object 'type'.
Type information is used by the virtual machine for excluding expensive
lookups.
In your case there no any type information about the object. So virtual
machine will have to perform lookup every time *any* message is sent to
the object.
So I would suggest to preserve the idea of using _map_ in each object
transparently.

> 
> But it is a *very* interesting question if these should be arrays or
> linked lists -
> 
>   Lists: + can be shared as the continuation (CDR) of several other
>                lists
>             + can be scanned using a single pointer
>             - since you can point into the "middle" of a list there are
>                 many aliasing problems
>             - can't be indexed into

This is the next problem.
Imagine that every slot-access operation requires scanning through the
list of slots.

>             + can be as space efficient as arrays with special encoding
>             + easy to split and put together
> 
>    Arrays: - need three items for scanning: base, index and size
>                 + no need to waste more than one virtual address per
>                    array
>                 + access to any element is equally fast

I vote for arrays. :-)

> 
> It is easy to convert one into the other when you need to do some kind
> of processing for which the normal format is not very good.
> 
> > Do you want to use the same semantics for a objects, arrays and
> > hashes? Like, (1 2 3) - array, (x 3 y 4) - object or hash?
> > Please describe that semantics a bit more.
> 
> Every object is a list, but there are lists which are not formatted
> objects (the code examples below, for instance). So I must treat (1 2
> 3) as an object which does not explicitly list the messages it
> understands. In fact, the object "1" has this problem as well, but at
> least the number objects have special tags so they don't look like they
> might be a regular object. I am still figuring this out.
> 
> > >     append '(z 9) '(x 3 y 4)
> >
> > Is this a message-sending construction? What is the receiver?
> 
> No, this was a pseudo Lisp functional notation. This would be more
> proper
> 
>    '(z 9) append: '(x 3 y 4)
> 
> though the problem above shows itself here: how does the '(z 9) object
> understand the 'append:' message? We would have to force it to be
> treated as a plain list, which is getting into the reflective level and
> similar to requesting a mirror for an object in Self.

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

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

> 
> This needs some careful design.
> 
> > How to distinguish objects and methods?
> 
> I am thinking of making methods internally be objects that have a
> special <code> "slot"
> 
>  ... factorial: (n 0
>                      <code> (n < 1 ifTrue:False: 1 '(n * factorial: n-1)
>                                    )
>                     ) ....
> 
> I have other ideas for blocks than quoted lists, but this will do for
> now. Hmmm... if instead of "<code>" I used "|" then this would look
> more like Smalltalk...

I thought about using the second variant too.

> 
> Note that though the argument "n" has a default value of 0, it will be
> replaced once this code object is cloned to create a context object.
> 
> > Did you get rid off keyworded selectors like a:B:C:?
> 
> I used one in the above example, but at the low level the keywords
> aren't spread among the arguments. In a higher level graphical editor I
> would expect you to be able to write something like
> 
>     n < 1 ifTrue: 1 False: [n * factorial: n - 1]
> 
> 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?
How are you planning to handle 'resend.' and '_parent_.' constructions?


Uladzimir.



More information about the Self-interest mailing list