From: Nils Gösche
Subject: Re: Mapping tables
Date: 
Message-ID: <87pt94x8ao.fsf@darkstar.cartan.de>
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
From: Dave Roberts
Subject: Re: Mapping tables
Date: 
Message-ID: <a2Vpc.63965$xw3.3726664@attbi_s04>
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