Apoorv Jain
Apoorv Jain

Reputation: 113

Update functions in Hash Table in Racket

I am a beginner in Racket and I am trying to updare a hash table using hash-update! where the value is a mutable set. Below are the code lines:

(hash-update! hash key (curryr set-add! new_val) (mutable-set 1))

However I receive an error

 expected: set?
given: #<void>
argument position: 1st
other arguments...:
  x: 2

where I tried 2 as the new_val

Any suggestions ?

Upvotes: 1

Views: 333

Answers (1)

Alex Knauth
Alex Knauth

Reputation: 8373

This is because the updater is supposed to be a function that takes a value as input and produces a new value output. Since the set is mutable and you're using set-add! to mutate it, the "updater" isn't returning a new value, just mutating the old one and producing void.

There are two ways to fix this:

  1. Mutable sets as values, mutate them separately, not inside hash-update!.
  2. Immutable sets as values, use a functional updater inside hash-update!.

Since you specified you want the values as mutable sets, I will show (1).

The most basic thing you can do is hash-ref to get a mutable-set, and then use set-add! on that.

(set-add! (hash-ref hash key) new-val)

However, this doesn't work when there is no mutable-set value for that key yet. It needs to be added to the table when it doesn't exist yet which why is why you have the (mutable-set 1) failure-result argument. The solution to this isn't hash-update!, it's hash-ref!.

(set-add! (hash-ref! hash key (mutable-set 1)) new-val)

Although it would probably be better if you wrapped the failure-result in a thunk

(set-add! (hash-ref! hash key (λ () (mutable-set 1))) new-val)

Upvotes: 1

Related Questions