This is a short description of something I'm considering doing in the
next couple of weeks: adding some support for abstract reflection to
Reflection in Self (as currently implemented with mirrors) provides
good support for concrete operations, such as determining the
low-level type of an object, the construction of an object's slots,
and so on. However, there isn't very much support for more abstract
queries - such as determining whether an object can behave in a
particular way, or more generally, answering the question: what "kind"
of object am I dealing with.
Now, determining kinds of objects isn't very good Self style, however
in some situations it is unavoidable. The current Self world has to
make abstract judgements about objects in several situations, mostly
concerned with aspects of the interface. For example, the UI must work
out how an objects is to be displayed (boxBlueprints maps kinds of
objects to display policies); the debugger must provide useful names
of objects; and the prompt must determine whether an object is
printable. Similarly, my program visualisation system will need this
information to match visualisations to target objects; to provide
context-sensitive operations; and even to pick the icons to use.
Currently, there isn't any support for these operations and so they
are performed in an ad-hoc manner. The boxBluprints object maintains a
local dictionary containing object descriptions (sets of slot names),
and methods for managing such mappings are local to boxBlueprints. The
debugger prints names such as "child of someobject". And the prompt
uses low-level branding of objects (seeing whether they contain a
"thisObjectPrints" slot) to decide if they should be printed.
My intention is to add "kind cache", similar to the existing pathCache
to manage this sort of information. The kind cache will map object
_patterns_ (slot-by-slot definitions, much like boxBlueprint) to
_kinds_ (objects which maintain the abstract reflexive information).
This information could be collated on a per-object basis, but I think
this would be too slow. So kinds will categorise objects into their
clone families, replicating in the Self world the use of maps in the
implementation. Many kinds could be (existentially) named, by finding
a well-known object in that clone family. Kinds could then be used
straightforwardly in boxBlueprints (rather than the list of slot
names), and the debugger could use the kind name for objects, rather
than their main parent.
The printing problem is more complicated. Kinds can easily determine
whether particular families of objects understand "printString" and
associated messages, but not whether they can usefully respond (the
object in question could be a trait or mixin). The kind system will
make some guesses about the object to determine this (initially using
the existing "thisObjectPrints" brand); considering the position of
any well-known family members in the name space is another
Finally, it should be possible to add interface or protocol
definitions (or glean them from the system) and then maintain this
information in kinds. (Essentially adapting Cook's work on interfaces
within Smalltalk to Self). This should allow efficient determination
of an object's compliance with a particular protocol in terms other
than the object's position in an interface hierarchy (i.e. object's
internal structure), and could be used to meet the user interface
needs of my application.
James "kjx" Noble
PS - Of course, kinds could also be called "classes" or "types". But I
prefer not to.
James Noble, Graduate Student, Computer Science Department
Victoria University, Box 600, Wellington 1, New Zealand