Wrap it in a function that handles hinting for you. Then use that instead of a straight deref..
user> (set! *warn-on-reflection* true)
true
user> (def the-ref (delay (java.util.HashMap. )))
#'user/the-ref
user> (defn realize-map ^java.util.HashMap [some-ref]
@some-ref)
#'user/realize-map
user> (doto (realize-map the-ref) (.put :a 2))
{:a 2}
You could generalize with protocols (or multimethods). Here's a protocol variant...
(defprotocol IMapthing
(retrieve [this arg])
(insert [this k v]))
(extend-protocol IMapthing
clojure.lang.Delay
(retrieve [this k] (retrieve @this k))
(insert [this k v] (do (insert @this k v) this))
java.util.HashMap
(retrieve [this k] (.get this k))
(insert [this k v ] (.put this k v)))
user> (def the-delay (delay (java.util.HashMap.)))
#'user/the-delay
user> (insert the-delay :a 2)
#<Delay@2ae7ca5b: {:a 2}>
user> (retrieve the-delay :a)
2
There are other schemes, but these are the least intrusive to me.