Reimplementation of clojure.walk with protocols