Dave Roberts <·············@re-move.droberts.com> writes:
> Simply, what is the best way to create a nice mapping table from
> integers<->symbols. In my case, I want to map from symbols
> representing DNS types (A, MX, TXT, etc.) to the corresponding type
> codes. I need to do this both directions, from symbols to codes when
> creating a query, and from codes back to symbols when decoding the
> response. I have tried this a couple ways before this, but they
> always felt kludgy.
>
> First attempt was simple a-lists. Write two functions to use ASSOC
> and RASSOC and we're in business. Nicely data driven.
>
> But then I started to think speed. A-lists are not fast when the
> size is large.
Either alists and ASSOC/RASSOC or a pair of hash tables are the
obvious choice here, I'd say. Which is faster depends on how much
data there is. Another possibility might be to use a hash table for
the integer->symbol direction, and for the other one put the number
onto the symbol's property list by some name.
> So, then I went to a version using two functions with hard-coded
> CASE forms. Works great, but now I have to remember to add mappings
> into two places.
>
> Then... I started to think that this is an ideal place to use macros. Why
> not give myself a nice syntax like creating an a-list, but then transform
> that into a case statement. Here's what I came up with. It feels kludgy and
> probably has all sorts of other macrology issues.
>
> So, please tell me if you would do this differently. If so, how? If you'd do
> it like this, how does my code look?
[snip code]
Nice, too, and the code looks good to me. Some things I would write
differently: I'd make ARG a gensym. I'd also let the user specify the
names of both mapping functions: Instead of calling CONCATENATE and
INTERN, use NAME1 and NAME2 directly. Then, perhaps, use CCASE
instead of CASE if the user doesn't specify any default arguments
(which I'd make keywords, I guess).
Regards,
--
Nils G�sche
"Don't ask for whom the <CTRL-G> tolls."
PGP key ID 0x7E4651AD
Nils Gösche wrote:
> Either alists and ASSOC/RASSOC or a pair of hash tables are the
> obvious choice here, I'd say. Which is faster depends on how much
> data there is. Another possibility might be to use a hash table for
> the integer->symbol direction, and for the other one put the number
> onto the symbol's property list by some name.
Yup, the symbol->number direction screams for a plist. You and David Steuber
win the prize. That's the sort of answer I was looking for. I figured there
was some list feature I had overlooked. That was it.
>
> Nice, too, and the code looks good to me. Some things I would write
> differently: I'd make ARG a gensym. I'd also let the user specify the
> names of both mapping functions: Instead of calling CONCATENATE and
> INTERN, use NAME1 and NAME2 directly. Then, perhaps, use CCASE
> instead of CASE if the user doesn't specify any default arguments
> (which I'd make keywords, I guess).
Thanks. Good input.
--
Dave Roberts, ·············@re-move.droberts.com
Slowly but surely, the programming world is finding Lisp...
http://www.findinglisp.com/blog