Clojureのderefをオーバーライド

Clojureはリーダマクロを自分で定義できないが、clojure.lang.IDerefのderefをオーバーライドしてやれば少し近いことができる。これはfuture-callでも使われている。

(def awkwardCounter
   (let [n (atom 0)]
      (proxy [clojure.lang.IDeref] []
         (deref []
            (swap! n inc)
            @n))))

@awkwardCounter ;=> 1
@awkwardCounter ;=> 2
@awkwardCounter ;=> 3
@awkwardCounter ;=> 4

valAtをオーバーライドしても楽しいかもしれない。

(def awkwardGreeter
   (proxy [clojure.lang.ILookup] []
      (valAt [key]
         (str "Hello " key))))

(:world awkwardGreeter) ;=> "Hello :world"