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

Re: Multiply-keyed collection classes



If I were doing it, I would implement the dfa as a subclass of
<table> and define a 'table-protocol' that combines both of the keys.
The function 'sequence-hash' from the 'table-extensions' library
might be a reasonable place to start.

Neel Krishnaswami wrote in message ...
>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: References: