Ответ 1
Вам нужно исключить функции, которые импортируются ядром:
(ns your-ns
(:refer-clojure :exclude [+ ...]))
(defn + ...)
Каков правильный способ переопределить метод типа "+"? Прямо сейчас у меня
(defn- + [x y] (replacement x y))
но это приводит к предупреждениям в командной строке.
WARNING: + already refers to: #'clojure.core/+ in namespace: <MY-NAMESPACE>, being replaced by #'<MY-NAMESPACE>/+
Вам нужно исключить функции, которые импортируются ядром:
(ns your-ns
(:refer-clojure :exclude [+ ...]))
(defn + ...)
Хотя я не рекомендую переопределять основные функции, такие как +, вы можете использовать привязку или позволить этому, это зависит от того, какое поведение вы хотите:
(let [+ -] (reduce + [1 2 3])) ; -4
(defn my-plus [x] (reduce + x))
(let [+ -] (my-plus [1 2 3])) ;6
(binding [+ -] (my-plus [1 2 3])); -4
Как было сказано в комментариях ниже, привязка больше не работает таким образом, поскольку clojure 1.3, так как var должен быть динамическим, а +, - и т.д. - нет.
Для целей тестирования/издевательств вы, однако, можете получить подобное поведение. В этом случае посмотрите с redefs (поскольку clojure 1.3): http://clojuredocs.org/clojure_core/clojure.core/with-redefs
Также смотрите: Пусть vs. Binding в Clojure
Вы действительно хотите это сделать? Если да, вы можете использовать defprotocol, чтобы указать, какие операторы вы хотите переопределить и расширить классы, для которых вы хотите, чтобы эти переопределения были реализованы. Для (надуманного) примера см. Мой ответ на этот вопрос.
Вы также можете переопределить встроенную арифметику, используя общие интерфейсы от contrib, для простого примера см. следующее:
http://nakkaya.com/2010/08/02/using-clojure-contrib-generic-interfaces/