Mutating hash-map while iterating

32 views
Skip to first unread message

zeRusski

unread,
Jun 3, 2019, 11:45:58 AM6/3/19
to Racket Users
Is it ok to mutate a hash while iterating over it say in one of ~for~ forms?
Specifically I want to filter (that is drop) some keys, but I'm also interested in
mutation in general. I guess the answer lies in whether forms like ~in-dict~ etc
create lazy streams that hold on to the table?

Relevant docs that I managed to dig out: 
- hash-map seems to suggest that at least dropping keys is fine, but that only
  talks about hash-map procedure specifically not other forms;

Here're some examples to be concrete:

#+begin_src racket
  ;; IMO ok according to docs?
  (hash-map h (λ (k v) (when (pred v) (hash-remove! h k))))

  ;; probably ok assuming it translates to hash-map?
  (dict-map h (λ (k v) (when (pred v) (dict-remove! h k))))

  ;; is that ok?
  (for (((k v) (in-dict h))
        #:when (pred v))
    (dict-remove! h k))

  ;; defensive solution
  (let ((fails (for/list (((k v) (in-dict h))
                          #:when (pred v))
                 k)))
    (for-each (curry dict-remove! h) fails))
#+end_src

That question wouldn't arise were I to deal with immutable data, but I'm not.

Ben Greenman

unread,
Jun 3, 2019, 2:07:44 PM6/3/19
to zeRusski, Racket Users
You want the paragraph just above the caveat about concurrent modification:

> A hash table can be used as a two-valued sequence (see Sequences). The keys
> and values of the hash table serve as elements of the sequence (i.e., each
> element is a key and its associated value). If a mapping is added to or
> removed from the hash table during iteration, then an iteration step may fail
> with exn:fail:contract, or the iteration may skip or duplicate keys and
> values. See also in-hash, in-hash-keys, in-hash-values, and in-hash-pairs.

https://docs.racket-lang.org/reference/hashtables.html

zeRusski

unread,
Jun 4, 2019, 4:29:30 AM6/4/19
to Racket Users
Thank you Ben. That answers my question. About what I expected - be defensive when in doubt.
Reply all
Reply to author
Forward
0 new messages