Re: Hashtables in guile.

Harvey J. Stein (hjstein@bfr.co.il)
14 Aug 1998 08:57:08 +0300

thi <ttn@netcom.com> writes:

> hjstein@bfr.co.il (Harvey J. Stein) writes:
>
> > How are hash tables supposed to work in guile? How good are they?
> >
> > In particular:
> > 1. How does one make a hash table? The manual talks about things
> > like hashq-ref, hashq-set! & hashq-remove!, but never says how to
> > make a hash table. This was surprising. Is it just a vector or
> > is it a separate type?
>
> one way:
>
> (define (make-hash) (make-array '() 431)) ; munge prime to taste
>
> yes, it's just a vector.

It's better for it to be prime? What is it, just modulo address for a
symbol? That's too bad, since it's not so easy to pick large primes
if necessary. Yes, I know it's easy enough to make a table
of them for this purpose, but that's not nearly as convenient as
having hash fcns which work well with a table size of 2^n.

> > 2. Do they grow dynamically or does their size remain fixed? If they
> > remain of fixed size, are there any particular sizes that are most
> > efficient for the default hashing fcns? Also, if they remain of
> > fixed size, why?!?! I've always found the STk hash tables (based
> > on the TCL code) that grow dynamically to be extremely efficient &
> > convenient to use.
>
> they are fixed because they are implemented in user space as arrays.
> anyone is free to write `rehash'.

So? They could be a cons cell with car = HASH_TABLE & cdr a vector.
Then the cdr could be replaced with a new vector (if that's what's
necessary for growing a vector).

> > 3. What about mapping over a hash table? How can I get all the key
> > value pairs out of the hash table? Is the hash table a vector of
> > alists? It doesn't say anywhere, so there's no documented
> > mechanism/fixed API for doing such things.
>
> (ht->list HASH-TABLE) gives you a list of key/value pairs amenable to
> `map' or `for-each'.

Nothing of the sort seems to exist:

hjstein@bacall:~/scwm$ guile
guile> ht->list
ERROR: In expression ht->list:
ERROR: Unbound variable: ht->list
ABORT: (misc-error)

Type "(backtrace)" to get more information.
guile> hash->list
ERROR: In expression hash->list:
ERROR: Unbound variable: hash->list
ABORT: (misc-error)
guile> hash-table->list
ERROR: In expression hash-table->list:
ERROR: Unbound variable: hash-table->list
ABORT: (misc-error)
guile> (apropos 'hash)
the-scm-module: hash-set! #<primitive-procedure hash-set!>
the-scm-module: hash-ref #<compiled-closure #<primitive-procedure gsubr-apply>>
the-scm-module: hash-create-handle! #<primitive-procedure hash-create-handle!>
the-scm-module: hashv #<primitive-procedure hashv>
the-scm-module: hash-get-handle #<primitive-procedure hash-get-handle>
the-scm-module: read-hash-procedures
the-scm-module: make-weak-key-hash-table #<primitive-procedure make-weak-key-hash-table>
the-scm-module: hashx-set! #<compiled-closure #<primitive-procedure gsubr-apply>>
the-scm-module: hashv-set! #<primitive-procedure hashv-set!>
the-scm-module: hashq-set! #<primitive-procedure hashq-set!>
the-scm-module: hashv-remove! #<primitive-procedure hashv-remove!>
the-scm-module: hashq-remove! #<primitive-procedure hashq-remove!>
the-scm-module: read-hash-extend #<primitive-procedure read-hash-extend>
the-scm-module: hashq-get-handle #<primitive-procedure hashq-get-handle>
the-scm-module: hashv-get-handle #<primitive-procedure hashv-get-handle>
the-scm-module: hashx-get-handle #<compiled-closure #<primitive-procedure gsubr-apply>>
the-scm-module: weak-value-hash-table? #<primitive-procedure weak-value-hash-table?>
the-scm-module: make-weak-value-hash-table #<primitive-procedure make-weak-value-hash-table>
the-scm-module: hashx-create-handle! #<compiled-closure #<primitive-procedure gsubr-apply>>
the-scm-module: hashv-create-handle! #<primitive-procedure hashv-create-handle!>
the-scm-module: hashq-create-handle! #<primitive-procedure hashq-create-handle!>
the-scm-module: hashx-ref #<compiled-closure #<primitive-procedure gsubr-apply>>
the-scm-module: hashv-ref #<compiled-closure #<primitive-procedure gsubr-apply>>
the-scm-module: hashq-ref #<compiled-closure #<primitive-procedure gsubr-apply>>
the-scm-module: unhash-name #<primitive-procedure unhash-name>
the-scm-module: weak-key-hash-table? #<primitive-procedure weak-key-hash-table?>
the-scm-module: hash #<primitive-procedure hash>
the-scm-module: make-doubly-weak-hash-table #<primitive-procedure make-doubly-weak-hash-table>
the-scm-module: make-hash-table #<procedure make-hash-table (k)>
the-scm-module: hashq #<primitive-procedure hashq>
the-scm-module: source-whash
the-scm-module: symbol-hash #<primitive-procedure symbol-hash>
the-scm-module: doubly-weak-hash-table? #<primitive-procedure doubly-weak-hash-table?>
the-scm-module: hash-remove! #<primitive-procedure hash-remove!>
guile> (apropos 'ht)
the-scm-module: substring-move-right! #<primitive-procedure substring-move-right!>
the-scm-module: vector-move-right! #<compiled-closure #<primitive-procedure gsubr-apply>>
guile>

>
> i found in the (old old) guile docs a section on the "dictionary
> convention" that was useful. dunno if that's still around somewhere.

It still exists, but it doesn't (as I mentioned) answer the questions
I posted.

-- 
Harvey J. Stein
BFM Financial Research
hjstein@bfr.co.il