如何在Clojure中重命名操作?

时间:2010-05-14 07:46:41

标签: clojure functional-programming

在我的列表中,另外,操作+显示为#。我怎样才能使它看起来像+?当我评估它时,它也应该与+。

完全相同

我想这也适用于Clojure中的各种函数...... 谢谢你们。

2 个答案:

答案 0 :(得分:5)

#字符在Clojure中的符号名称中不是有效字符(有关有效字符的列表,请参阅this page),虽然它有时可能有效(通常会有效),但它是使用它不是一个好习惯。此外,它肯定不会在符号的开头(实际上是文字,你仍然可以(symbol "#"),尽管可能没有意义)。正如Clojure读者目前所认为的那样,没有什么可以做的(除了可能会将读者打开以便将#(即'#'后跟空格)视为符号# - 或者只是+ - 虽然这是你真的不应该做的事情,所以我几乎感到内疚,因为a link提供了如何做的指示。)

如果您想将名称别名为Clojure中合法的其他名称,您可能会发现使用clojure.contrib.def/defalias宏而不是普通def会很方便;这有额外的好处是为你设置元数据(并且应该处理宏,虽然它似乎有一个错误,在此时阻止,至少在1.2 HEAD)。


如果您想在创建别名时重新定义一些内置名称...(如果不这样做,其余部分可能与您无关。)

首先,如果您使用Clojure 1.1或更早版本并且想要为clojure.core中的名称提供自己的绑定,则在定义命名空间时需要使用:refer-clojure。例如。如果您想提供自己的+

(ns foo.bar
  (:refer-clojure :exclude [+]))

;; you can now define your own +
(defn + [x y]
  (if (zero? y)
    x
    (recur (inc x) (dec y))))

;; examples
(+ 3 5)
; => 8
(+ 3 -1)
; => infinite loop
(clojure.core/+ 3 -1)
; => 2

Clojure 1.1对此结果的需求禁止重新引用在其他名称空间中引用Vars的名称; ns-unmap提供了一种适合REPL使用的方法,而(:refer-clojure :exclude ...)(:use :exclude ...)(:use :only ...)提供了系统的方法来防止在第一个名称空间中导入不需要的名称的地方。

在当前的1.2快照中,有一个“last-var-in wins”策略,所以你可以不用:refer-clojure;但它仍会生成编译器警告,并且使用:refer-clojure的方式更好,而且无法保证此策略在实际的1.2版本中仍然存在。

答案 1 :(得分:1)

操作只是一段代码,分配给变量。如果要重新绑定操作,只需重新绑定该变量:

(def - +)
(- 1 2 3)
# => 6

这里唯一的问题是#字符在Clojure中是特殊的。我不确定你是否可以使用#作为变量名 ,至少你需要在绑定时引用它,也可能在调用时引用它:

(def # +)
# => java.lang.Exception: No dispatch macro for: 

不幸的是,我对Clojure不太熟悉,不知道如何引用它。