Every time I think I have a good use for hash impersonators, it turns out they 
don't work the way I expect. 

So I'll invert the question: in what situation is a hash impersonator the best 
tool for the job? (Or, have they been eclipsed by other language features like 
`gen:dict`?)  

IIUC, `impersonate-hash` is mostly for situations where I can treat the 
underlying data source as having a  set of keys that can't be changed by 
another process. A hash impersonator could work, say, for making a hash where 
keys are case- and type- insensitive, so things like "FOO" and "fOO" and 'Foo 
are all treated as key 'foo.

But let's look at a more interesting PLT example [1], where a hash impersonator 
wraps an IMAP server. The keys are mailboxes, and the values are the mailbox 
messages (which are loaded lazily via `hash-ref`):

(define (imap-hash server user pass)
  (define-values (conn c r) (imap-connect server user pass "INBOX"))
  (define mailboxes (map second (imap-list-child-mailboxes conn #f)))
  (imap-disconnect conn)
  (impersonate-hash
   (make-hash (map (λ (m) (cons m #f)) mailboxes))
   (λ (h k) (values k (λ (h k v) (imap-mailbox-vector server user pass k))))
   (λ (h k v) (error "assign not allowed"))
   (λ (h k) (error "remove not allowed"))
   (λ (h k) k)))

That's fine as far as it goes. But it also has an obvious shortcoming: though 
`imap-hash` claims to wrap a dynamic data source, there's no way to keep the 
its keys synchronized with the IMAP server.

For instance, suppose I'm using `imap-hash`, and during my session, ten new 
mailboxes are added to the IMAP server. AFAICT, `imap-hash` won't see those 
(unless I explicitly add them using `(hash-set! imap-hash ...)` but the point 
of hash impersonation is to hide that housekeeping.)

You could say, "well just run your program again, and it'll pick up the new 
mailboxes." But if you're using `imap-hash` in a web servlet, that doesn't 
work, because the servlet runs indefinitely.

You could say, "well refresh your keys when you get a `hash-ref`". But that 
won't work, because the lambda that handles `hash-ref` in a hash impersonator 
"is called only if the returned key is found". [2] 



[1] https://www.cs.umd.edu/~sstrickl/chaperones/chaperones-oopsla2012.pdf
[2] 
http://docs.racket-lang.org/reference/chaperones.html?q=impersonate-hash#%28def._%28%28quote._~23~25kernel%29._impersonate-hash%29%29
 
<http://docs.racket-lang.org/reference/chaperones.html?q=impersonate-hash#(def._((quote._~23~25kernel)._impersonate-hash))>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to