Это немного сложно, но с помощью псевдонима макроса в clojure.core
это возможно.
Откройте репл и следуйте приведенным ниже инструкциям.
➜ ~ clj
Clojure 1.9.0
Первый псевдоним clojure.core/defn
к чему-то другому:
user=> (in-ns 'clojure.core)
#object[clojure.lang.Namespace 0x48e92c5c "clojure.core"]
clojure.core=> (defmacro defn-holder [])
#'clojure.core/defn-holder
clojure.core=> (alter-var-root #'defn-holder (constantly (var-get #'defn)))
#object[clojure.core$defn__5154 0xd3957fe "clojure.core$defn__5154@d3957fe"]
Затем создайте новый макрос defn, который использует определение псевдонима
clojure.core=> (in-ns 'user)
#object[clojure.lang.Namespace 0x64ba3208 "user"]
user=> (defmacro defn [& args] `(do (println "aliased version")(clojure.core/defn-holder ~@args)))
WARNING: defn already refers to: #'clojure.core/defn in namespace: user, being replaced by: #'user/defn
#'user/defn
user=> (defn foo [a])
aliased version
#'user/foo
user=> (foo 1)
nil
Однако он пока не работает для всех пространств имен:
user=> (ns bar)
nil
bar=> (defn foo [a])
#'bar/foo
Нам нужно переопределить defn в clojure.core с нашим новым определением:
bar=> (in-ns 'clojure.core)
#object[clojure.lang.Namespace 0x48e92c5c "clojure.core"]
clojure.core=> (alter-var-root #'defn (constantly (var-get #'user/defn)))
#object[user$defn 0x37052337 "user$defn@37052337"]
Теперь это работает:
clojure.core=> (in-ns 'bar)
#object[clojure.lang.Namespace 0x37efd131 "bar"]
bar=> (defn foo [a])
aliased version
#'bar/foo