[Prev][Next][Index][Thread]

Multiply-keyed collection classes



Hello all, 

I have another question about how to properly write Dylan collection
classes.

What's the right way of building of building collection classes whose
keys are logically tuples of non-integer objects? Ideally, I'd like to
be able to write code like this (for a hypothetical regexp engine):

  ...
  let new-state = dfa[old-state, character];
  ... 

which looks like a job for the aref generic. However, the description
of the aref generic in the DRM is: 

  Signature:
      aref array #rest indices => element
     
  Arguments:
      array An instance of <array>.
  
      indices
  	  Instances of <integer>.

and the description of the <array> class reads "...[<array> is the]
class of collections whose elements are arranged according to a
Cartesian coordinate system. [...]  An array element is referred to by
a (possibly empty) series of indices. The length of the series must
equal the rank of the array. Each index must be a non-negative integer
less than the corresponding dimension." This seems to preclude using
non-integer indices with aref and still obey the <array> contract.

Right now, I see two possible solutions, neither of which is
completely satisfactory:

1. I could just ignore this by defining an <array> subclass with an
   aref method that takes <object> indices, since AFAIK there isn't a
   way to specialize #rest args to a specific class. But that seems
   like an abuse/hack, and I'd prefer to avoid it if I can.

2. I could just write a different method that reads like:
   
     let new-state = lookup(dfa, old-state, character);

   This works fine, but isn't nearly as pretty as being able to use
   aref for the bracket syntax.

3. I could add a slot to the dfa class, that contains a function that
   calls lookup, so I could write:

     define method find(dfa :: <dfa>) => (f :: <function>)
       curry(lookup, dfa)
     end method find;

   and then:

     let new-state = dfa.find(old-state, character);

   But this is just twisted, and hence doesn't count. :)


Neel



Follow-Ups: