在(def + - )之后,有没有办法让+运算符添加而不是减去?

时间:2016-09-05 12:20:30

标签: clojure

我正在学习Clojure。与Python相比,看看我是否可以做一些古怪的事情,我做了:

> (+ 2 2)
4
> (def + -)
#'sandbox6693/+
> (+ 2 2)
0

令人惊讶地工作,但是我无法弄清楚如何在上面的定义之后再次添加+。有办法吗?

2 个答案:

答案 0 :(得分:2)

正如@Russell所说,你只是用clojure.core/+隐藏user/+

我将如何尝试使用clojure,只是建立一些本地绑定(再次使用+将核心+隐藏起来,但将更改保留在绑定范围内,而不是乱七八糟):

user> (let [+ -]
        (+ 1 2 3))
-4

user> (+ 1 2 3)
6

但总的来说,有一些特殊的方法可以做你想要的(改变var的值,在var更改的范围内执行一些代码,然后自动恢复它的值):

第一个是使用bindinghttps://clojuredocs.org/clojure.core/binding)问题是它仅适用于特殊dynamic变量,因此它不适用于您的情况,因为{ {1}}不是动态的

第二个,是使用更接近你需要的+https://clojuredocs.org/clojure.core/with-redefs),但那里有一个问题:

with-redefs

第二个示例失败,因为编译器内联user> (with-redefs [+ -] (+ 1)) -1 ;; as expected user> (with-redefs [+ -] (+ 1 2 3)) 6 ;; unexpected! 函数,当有多个arg传递给它并用+函数调用替换它时)

此外,对于某些纯粹教育目的,您可以创建一个宏,通常会重新定义您需要的所有内容,保存旧值,并在块评估后恢复它:

add

答案 1 :(得分:1)

我不认为您正在移除clojure.core函数+,只是在您的命名空间中遮蔽它。

您可以通过重新引用+作为clojure.core中的函数来引导它,包括命名空间:

user=> (def + -)
#'user/+
user=> (+ 2 2)
0
user=> (def + clojure.core/+)
#'user/+
user=> (+ 2 2)
4

但......为什么?!