[comp.lang.eiffel] Tricky usage of deferred classes

jellinghaus-robert@CS.Yale.EDU (Rob Jellinghaus) (03/09/89)

I am currently writing a general cellular automaton (CA) class system in
Eiffel, and I am running into conceptual difficulties with the deferred class 
mechanism.  (I apologize for this posting's length.)

The behavior I want is as follows:  I would like to define a class CA_LOCATION
which represents one location in the CA's space.  (Note that the space may
be 2-D, 3-D, hexagonal, N-dimensional... it's undefined.)  Then I want two
other classes, CA_CELL and CA_ACTION, that represent a cell in the CA (a
CA_LOCATION with some state information), and a transformation on a particular
location (a CA_LOCATION with routines defining what happens to the cell).
Note that all these classes are deferred; that is, an actual use of this
class system would inherit from these classes in creating the LOCATIONs, CELLs,
and ACTIONs specific to that particular CA.

The essential point is that both CA_CELLs and CA_ACTIONs inherit from the
same CA_LOCATION class, *for any given CA*.  That is, if I'm creating Conway's
Life (which I am), I would like to define CONWAY_LOCATION (which would
inherit from the deferred CA_LOCATION class), CONWAY_CELL and CONWAY_ACTION.
But there is no way to enforce that CONWAY_CELL inherits from both CONWAY_
LOCATION *and* CA_CELL, which is the desired effect.  (Is there?)

I am currently going to document in both CA_CELL and CA_ACTION that the
actual instantiations of cells and actions in the particular CA should
inherit from a common LOCATION class.  Thus, I am moving away from getting
the language to require such behavior, and instead leaving it up to the
programmer to write a correct class.  I would rather Eiffel could do it.

That's not all, though.  I'm also writing my own hash table classes, based
on a deferred class HASHABLE, which must be a parent of any type which can
be stored in my HASH_TABLE and LINKED_HASH_TABLE classes.  HASHABLE defines
a function hash: integer.  The reasoning is as follows: different data
types should know how to hash themselves most effectively, and hence each
type should implement its own hash function, returning an integer that is
some function of the datum.  (Eiffel 2.1's H_TABLE class takes a string as
a key, which seems fairly random to me.)  My HASH_TABLE[T -> HASHABLE]
class is simply a fixed-size table, and my LINKED_HASH_TABLE[T -> HASHABLE]
is a HASH_TABLE in which each bucket is a linked list.  (HASHABLE is a
conceptual twin to COMPARABLE, and the T -> HASHABLE notation indicates
that any T in a HASH_TABLE *must* inherit from HASHABLE.  This is constrained
genericity, described in the 2.1 library manual.)  The integer returned
from hash:integer is converted internally by HASH_TABLE into the index of
the array location containing the element.  What do people think of this
approach as opposed to the current H_TABLE?

And last but not least, there is another concept I wish to embody in a
deferred class.  Each CA will need to associate a table of cells, and two
linked lists of actions.  (The algorithm is: make all the changes in the
current list of actions, then create a new list by examining the new
board configuration.)  So what I would like is some way to write a deferred
class CA_WORLD with features board: LINKED_HASH_TABLE[C -> CA_CELL], and
two lists current: LINKED_LIST[A -> CA_ACTION] and next: <likewise>.  Is
this valid notation?  Can I specify, in a deferred class, that a feature
must be of some given type, while allowing for the children of the
class to write board: LINKED_HASH_TABLE[CONWAY_CELL]?  In other words, I
want to inform all descendants of CA_WORLD that the board feature MUST
be a LINKED_HASH_TABLE of descendants of CA_CELL, and let them define
exactly *which* descendant it is.  Is there any way to do this?  Or must
I, again, leave it up to the programmer?

You can see that I would like to extend the constrained-genericity
mechanism to enforce the relations between my classes... is there any way
to do this?  Or should I redesign my class structure?

Rob Jellinghaus                | "Next time you see a lie being spread or a
jellinghaus-robert@CS.Yale.EDU |  bad decision being made out of sheer ignor-
ROBERTJ@{yalecs,yalevm}.BITNET |  ance, pause, and think of hypertext."
{everyone}!decvax!yale!robertj |     -- K. Eric Drexler, _Engines of Creation_