I'm a Python programmer new to Racket...
I have seen some code like:
(define table/c (and/c hash? (not/c immutable?)))
I understand this to be a use of Contracts, i.e. https://docs.racket-lang.org/reference/data-structure-contracts.html#%28def._%28%28lib._racket%2Fcontract%2Fbase..rkt%29._and%2Fc%29%29
So it means that anywhere in this library which accepts a table/c
arg, it should be an object which is a mutable hash-table.
My question is... does Racket have any support for duck-typing here (specifically to satisfy the contract of hash?
)?
Say I wanted to replace the basic hash-table with something backed by a k/v store... Is there a 'hash-table' interface I could implement that would allow my store-backed custom object to pass a hash?
contract check?
The docs for contracts and this for the hash?
check didn't help me much.
I think you really want to use dictionaries for this, but if you're stuck with a library which wants hash?
for contract checks then you can use impersonators.
Here's a function I wrote which tries to use a weak hash has a cache for some possibly-expensive computation represented by the (misnamed) filler
function which will get called on a missing key.
I'm rather unsure about the semantics of this sort of thing (and I'm not an expert on any of this) but it works in practice.
(define (make-cache filler)
(impersonate-hash
(make-weak-hash '())
(λ (ht key)
;; impersonate hash-ref by calling the filler
(unless (hash-has-key? ht key)
;; I think this is safe as the key won't be dropped
(hash-set! ht key (filler key)))
(values key (λ (ht k v) v)))
;; Everything else is passed through
(λ (ht k v)
(values k v))
(λ (ht k)
k)
(λ (ht k)
k)))