Subject: Re: (make-hash-table :test #'mytest)
From: Erik Naggum <erik@naggum.no>
Date: 03 Nov 2002 18:58:46 +0000
Newsgroups: comp.lang.lisp
Message-ID: <3245338726772626@naggum.no>

* Knut Olav Bøhmer
| Is it possible to make ones own :test to use with hash-tables? if yes,
| how (where is the doc)? if no, why?

  This is actually very simple, but not immediately obvious because of the
  many choices to `make-hash-table´, which tends to make you look for ways
  to expand on those choices.  The better solution is to look another way
  entirely and realize that the key in the hash-table does not necessarily
  have to be the actual key.

  Even with `equalp´, which traverses structures, you still end up with a
  hash bucket that is some index into an array.  So the function has to do
  two things: compute some magic number and compare the item found in the
  hash-table to the actual key before returning the value in the hash-table.

  Your `mytest´ function would therefore have to consist of two functions:
  (A) One of one argument that returns a (numeric) hash key, and (B) one of
  two arguments that returns true if the two arguments are the same under
  your test and nil otherwise.  You might argue that the way we specify the
  `:test´ argument to `make-hash-table´ today is deficient in that it hides
  the details and pretends that real functions are involved when they are
  really keyword arguments from a finite set of values that select two or
  more aspects of the hash-table at once.

  To make your own hashtable work, you would therefore have to implement
  the bucket yourself, and each hash key you use would have to retrieve a
  list of potential values and scan it for the actual value you want.  One
  good way to do this is to find an orthogonal quality that can also be
  reduced to a `eq´-testable value and then use plists.  Then you build a
  few simple wrapper macros to make use of your improved hash table.

  In practice, your knowledge of the data you wish to store and retrieve
  will in the general case be superior to what you can express in any
  declarative language and it is therefore alluring the way politcal
  campaign promises are to choose some "simple" mechanism that covers
  another small area of the problem space in addition to the existing hash
  test functions, but then someone will come along to ask exactly the same
  question you did when they step outside that area, too.  Therefore, a
  standard has to strike a balance between convenience and simplicity.

  To wrap this up with a reference back to what I said at the top, the fact
  that you can get a bunch of test functions tends to make you look for a
  way to extend that list.  This is the wrong approach in general, but it
  is known to be hard to leave a path you think ought to be good.  There is
  even an idiom for it: To be stuck in a rut, where rut is literally a deep
  track made by the passage of a wheel.

-- 
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.