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