8

Experienced lisp, scheme, clojure programmer making the move to elisp from python for automating routine, everyday, basic tasks: I got an enormous surprise from the following in ielm

ELISP> (setq h2 (make-hash-table))
#s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8 data ())
ELISP> (puthash "a" 1 h2)
1 (#o1, #x1, ?\C-a)
ELISP> (gethash "a" h2)
nil

huh? The key and the value appear to be present:

ELISP> h2
#s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8 data ("a" 1))

/slaps forehead. I must be missing something totally obvious. Info says:

-- Function: gethash key table &optional default
 This function looks up KEY in TABLE, and returns its associated
 VALUE—or DEFAULT, if KEY has no association in TABLE.

great. Let's see if we can get gethash to return anything other than nil:

ELISP> (gethash "a" h2 'fubar) 
fubar

wow. Ok, I'm a lot dumber than I thought. What on earth am I doing wrong?

13

The default membership test for a hash table is eql. If you'd like to use a string as the key, set it to equal instead:

(setf hash (make-hash-table :test #'equal))
(puthash "a" 1 hash)
(gethash "a" hash)                      ; ==> 1

For reference, here's the relevant part of the docstring:

make-hash-table is a built-in function in `C source code'.

(make-hash-table &rest KEYWORD-ARGS)

Create and return a new hash table.

Arguments are specified as keyword/argument pairs. The following arguments are defined:

:test TEST -- TEST must be a symbol that specifies how to compare keys. Default is eql. Predefined are the tests eq, eql, and equal. User-supplied test and hash functions can be specified via define-hash-table-test.

  • I guess technically you're not passing a symbol as the :test parameter in your example... – Sean Jun 23 '15 at 23:43
  • string-equal might have some advantages over equal if I know my hash-table has strings only as keys. I am not sure why elisp has both string-equal and equal, because equal can be used any place that string-equal can be used modulo the fact that string-equal throws type errors when you don't give it strings. Maybe that's a desired behavior. – Reb.Cabin Jun 24 '15 at 17:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.