我正在学习Clojure。与Python相比,看看我是否可以做一些古怪的事情,我做了:
> (+ 2 2)
4
> (def + -)
#'sandbox6693/+
> (+ 2 2)
0
令人惊讶地工作,但是我无法弄清楚如何在上面的定义之后再次添加+。有办法吗?
答案 0 :(得分:2)
正如@Russell所说,你只是用clojure.core/+
隐藏user/+
。
我将如何尝试使用clojure,只是建立一些本地绑定(再次使用+
将核心+
隐藏起来,但将更改保留在绑定范围内,而不是乱七八糟):
user> (let [+ -]
(+ 1 2 3))
-4
user> (+ 1 2 3)
6
但总的来说,有一些特殊的方法可以做你想要的(改变var的值,在var更改的范围内执行一些代码,然后自动恢复它的值):
第一个是使用binding
(https://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
但......为什么?!