Menu

#5 Question/suggestion for hash-table page

open
nobody
None
5
2002-10-07
2002-10-07
No

I stumbled across this while looking for an answer to a
poignant hash-table question. Namely, how does one
make a hash-table whose entries are CLOS objects? The
spec only requires that hash-tables accept eq, eql,
equal, equalp as tests. Unfortunately, these are all
equivalent to EQ when applied to CLOS objects. And
none are generic functions. An answer to this question
would sure be helpful!

If I find a good one, I'll submit it.

Cheers,
R

Discussion

  • Nobody/Anonymous

    Logged In: NO

    I think you might be confusing CLOS objects with the ability to use GFs, so I want to ask: do you want a
    hash-table whose equality test is a GF, or a table which distinguishes CLOS objects by some means other than
    the four equality tests you (correctly) listed?

    If it's the first of these, then you're stuck. If it's the other you could write some code to extact the information you
    want out of a CLOS structure into - say - a list in such a form that equal would serve you.

    Hash-tables have to be restricted in this way, otherwise they'd be too inefficient to be usable. Maybe you shouldn't
    be using a hash-table?

    What are you trying to achieve? What would your equality test look like?

     
  • Robert P. Goldman

    Logged In: YES
    user_id=275595

    I wasn't confusing CLOS objects with the ability to use
    Generic Functions as a test in a hash table. But there is
    an obvious connection: since none of the existing equality
    tests are sufficient to test CLOS objects, a generic
    function is a logical way to implement an
    equality/equivalence test for CLOS objects in a hash table.

    Actually, it turns out that I'm NOT stuck. For CMUCL, one
    can make special-purpose hash tables using the (not
    well-documented) function define-hash-table-test, which
    allows you to provide a special hash-function/equality test
    combination for new kinds of hash tables.

    [I'm not sure what the situation is for Allegro, since I
    don't have a license any more, but I'm pretty sure I was
    able to make hash tables of objects there.]

    The CMUCL solution is actually just the Right Thing, because
    it allows you to provide two pretty simple pieces of
    information, and then use the hash-table functions as they
    are. Much better than having to do all kind of monkeying
    around with making lists out of objects, handling buckets
    and collisions yourself, etc.

    After all, if I wanted to write C, I could write C. I'm
    writing CL because (1) I need to do rapid prototyping and
    experiment with different data structures and (2) my time is
    more important than my Athlons'! So, with all due respect,
    *I* would prefer to be the judge of whether my hash table is
    going to be too inefficient to be usable. Not only do I
    want to use CL instead of C, I want to use CL instead of
    Pascal, the language that nags me! :-)

    I could write up instructions about how to use hash-tables
    for more ambitious things in CMUCL, but probably I would be
    better off offering to help fix the CMUCL documentation for
    this.

     
  • Nobody/Anonymous

    Logged In: NO

    Implementation dependant. In CMUCL, do something like
    (ext:define-hash-table-test 'foo #'foo-t #'foo-h), and then
    (make-hash-table :test 'foo) makes a hash table that uses
    (foo-t x y) to compare two items, and (foo-h x) to generate
    the hash value. [Of course, you have to make sure that
    (foo-t x y) implies (= (foo-h x) (foo-h y))]

     

Log in to post a comment.