[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: