[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
idea: slices (a bit long)
I have a few ideas I have been meaning to post
here about the future of Self. I would very much
like to get the opinion of all you selfish people,
but I have been hesitant to post such long messages
since I know how busy everybody is. Feel free to
complain if you think this kind of posting isn't
a good idea.
Selections are a common way of indicating objects to be affected by
commands in a graphical user interface. Slices are a generalization
of this idea to simplify the implementation and enhance the
usefulness of GUIs.
In an object oriented graphics framework, on-screen objects are normally
the result of a complex structure of basic shapes combined with
"wrappers" (modifier objects). If the structure can be an arbitrary
graph (or limited to non cyclic ones), then a single object might
control the appearance of several distinct on-screen objects. Sharing
a color wrapper among three objects, for example, would insure that
every time the color of one is changed the others automatically
change to match. In a drawing showing several PCs connected in
a network, as another example, a change to one of the PCs might
make it different from the others or the change can affect all
subdrawings in one swoop. In the first case the PCs would be several
copies of an original drawing (three distinct nodes in the object
graph) while in the second we would have a single drawing being
shown on the screen with several distinct translation wrappers.
This is roughly like the difference between clones and traits
or classes and instances. In the object-based spirit of Self,
the Morphic graphics framework doesn't work like this, but makes
each object responsible for all information related to it (color,
position, etc). This makes it impossible to do the kinds of operations
described above. It also makes it hard to extend the functionality
of the framework - rather than just adding a new rotation wrapper
we would have to include a rotation copy-down slot in the basic
morph and (possibly) have to rewrite many methods. On the other
hand, morphic is more concrete and easier to understand than most
One problem with traditional frameworks is that the kinds of operations
that can be done on an object are defined (and limited) by its
invisible structure. In the PCs example, we can either change a
single part of the drawing or all instances at once, and it is
not always clear by just looking at the image which one is the
case. If we need to do something different from what the current
structure allows, we first have to change that structure and then
do the operation. Imagine that we wish to modify in the same way
two instances of the drawing but leave the rest of them alone.
So expected operations were made easier at the cost of making
unexpected operations much harder. And the most common expected
operations are handled reasonably well by morphic's embedding
structure. So we need a way to make unexpected operations as
easy as possible.
The Sinclair ZX81 Basic had a very interesting feature called
"slices" (APL had a much more powerful implementation of the
idea, as did other systems, but I don't recall that they gave
a name to it). It allowed you to operate on a whole subset
of an array in a single operation. You could clear the middle
three elements in a short vector by executing A(3 to 5) = 0.
The idea of working with a subset of a collection of objects
is a common one in graphical user interfaces. You might select
two paragraphs in a long text to change their font to a larger
size or you might create a carpet morph in Kansas to move
several objects at once or to dismiss them. Rather than having
these kind of operations be ad hoc additions to the GUI, it
might be interesting to have them be instances of a more general
A slice is simply a collection whose elements are a subset of
the elements of another collection. So saying "slice do: [something]"
is simply a convenient shorthand for doing something to some
elements in the original collection but not to the others. The
slice must remember what collection its elements are from in
case the something you wish to do is removing them from that
original collection. Actually, the elements in a slice might
come from several distinct collections.
Graphically, a slice is a kind of "lightweight" object. It must
be very easy to create or destroy one. You might create one by
just dragging the mouse across some text and destroy it by
simply creating another one. You might create a slice as a
result of an operation (allImplementers, for example) and it
might persist until explicitly dismissed. When you pop up a menu
on a slice, it creates a menu which is the intersection of the
menus of all of its elements. So you can choose an operation
that can be done on all the elements (make a slice that includes
a drawing and some text, for example, and the menu might limit
you to changing their color).
It is interesting to note that the combination slices/persistent
objects makes a very nice poor man's database. It has the
functionality of the "find" command that all modern OSes have
copied from the Mac. You can use slices to choose if a change
to a slot should affect only a given object or all of its
clone family (this is even more flexible than Kevo or the
debugger/outliner distinction in Self 4).
The ability to create and manipulate lightweight slices of
objects allow one time structuring of objects and is a convenient
replacement for the more static structuring of conventional
graphics frameworks. It also has many non graphical applications,
being an interesting addition to Self's collection "types".
The main problem is that making operations on slices the same
thing as operating on all of its elements means that doing something
with the slice itself is very awkward. Imagine that the menu for
a carpet morphs listed operations to be done to the elements
contained in it, rather than to the carpet morph itself. We
might divide operations into three types:
- elements only: changing the color is a thing to be done
to each of the elements, but has no real effect on the
- elements and slice: moving the elements or resizing them
will obviously imply moving resizing the slice as well.
- slice only: adding new elements to a slice or removing
elements from it (and, maybe, asking its current size)
seem to be the only operations that can be done to the
slice but which shouldn't affect the elements.
The problem, then is finding a reasonable way to handle the
third kind of operations, both textually and graphically.
-- Jecel Mattos de Assumpcao Jr
Laboratorio de Sistemas Integraveis
University of Sao Paulo - Brazil