From ... Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!canoe.uoregon.edu!logbridge.uoregon.edu!news.tele.dk!news.tele.dk!small.news.tele.dk!newsfeed1.bredband.com!bredband!uio.no!nntp.uio.no!ifi.uio.no!not-for-mail From: Erik Naggum Newsgroups: comp.lang.lisp Subject: Re: (make-hash-table :test #'mytest) Date: 03 Nov 2002 18:58:46 +0000 Organization: Naggum Software, Oslo, Norway Lines: 52 Message-ID: <3245338726772626@naggum.no> References: Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Trace: maud.ifi.uio.no 1036349927 14254 129.240.65.205 (3 Nov 2002 18:58:47 GMT) X-Complaints-To: abuse@ifi.uio.no NNTP-Posting-Date: 3 Nov 2002 18:58:47 GMT Mail-Copies-To: never User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 Xref: archiver1.google.com comp.lang.lisp:45616 * 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.