Christopher Browne <[EMAIL PROTECTED]> writes:

> I have come to understand how Guile handles hashing; Rob Browning
> was looking, in .../scm/prefs.scm for a "hash-for-each."
> 
> I have some code in transit that handles this; that will also fairly
> substantively change the QIF code that I'm now actively fiddling with
> again.
> 
> ;;; Less-than-well-tested:
> (define (hash-for-each fun table)
>    (array-for-each
>       (lambda (sublst)
>          (if sublst
>                (for-each fun sublst)))
>         table))

I've finally gotten around to looking at this, and are you sure it's
correct?  It seems to assume that hashes will always be founded on
vectors of empty lists, and I don't think that's guaranteed.  In fact
I've always started my hashes with no values.  For example, I believe
this is a functionally acceptable guile hash:

  (define some-hash (make-vector 5))
  (hashq-set! some-hash 'a 1)
  (hashq-set! some-hash 'b 2)
  (hashq-set! some-hash 'c 3)

which ends up being

  guile> some-hash
  #(#<unspecified> ((c . 3) . #<unspecified>) #<unspecified> ((b . 2)
  . #<unspecified>) ((a . 1) . #<unspecified>))

and works just fine.

This ambiguity was why I didn't bother with hash-for-each before.  I
couldn't find in the docs a clear what defines a legitimate hash, so
it wasn't completely clear how to traverse it "correctly", and I
didn't really have to have hashes at the time.  I do seem to recall
that I asked about this on the guile list and there was a big debate
about what would be the optimal solution.

However, as a "good enough" solution, and presuming that we really
need hashes (we probably do), you could modify your code as indicated
below, and I think it'll work in all the likely cases:

  (define (hash-for-each thunk hashtable)
    (array-for-each
     (lambda (bucket)
       (if (pair? bucket)
           ;; Can't use for-each here since a bucket doesn't have to be
           ;; a proper list.  (make-vector 17) is a functional hash table.
           (let loop ((remaining-items bucket))
             (if (pair? remaining-items)
                 (begin
                   (thunk (car remaining-items))
                   (loop (cdr remaining-items)))))))
     hashtable))

-- 
Rob Browning <[EMAIL PROTECTED]> PGP=E80E0D04F521A094 532B97F5D64E3930

--
Gnucash Developer's List 
To unsubscribe send empty email to: [EMAIL PROTECTED]

Reply via email to