Clojure宏创建函数的同义词

Al *_*hou 6 macros clojure

对于任何真正知道如何在任何Lisp中编写宏的人来说,这可能是一个简单的方法.我希望能够为函数名定义同义词.我一直在复制和粘贴黑客core.clj这样做,但我不想永远是这样的傻瓜!很明显,一个宏将对synoym函数的调用重写为对原始函数的调用是正确的方法.

G__*_*G__ 13

如果我理解你的问题,有一种更简单的方法:将新符号定义为旧函数.

user=> (def foo +)
#'user/foo 
user=> (foo 1 2) 
3
Run Code Online (Sandbox Code Playgroud)

def的性能也优于宏观方法:

(defmacro foo2 [& args]
  `(+ ~@args))
Run Code Online (Sandbox Code Playgroud)

然后,foo2实际上是+的别名,并且行为完全相同(被重写为+),除了使用必须返回值的宏的限制.

如果您希望"别名"的行为与原始函数的行为完全相同(在相同的上下文中也可调用),那么您需要使用def来重命名该函数.

user=> (def foo +)

user=> (defn foo1 [& args]
         `(+ ~@args))

user=> (defmacro foo2 [& args]
         `(+ ~@args))

user=> (time (dotimes [n 1000000] (foo 1 n)))
"Elapsed time: 37.317 msecs"

user=> (time (dotimes [n 1000000] (foo1 1 n)))
"Elapsed time: 292.767 msecs"

user=> (time (dotimes [n 1000000] (foo2 1 n)))
"Elapsed time: 46.921 msecs"
Run Code Online (Sandbox Code Playgroud)

  • 我无法回答Clojure,但对于Scheme,使用`+`vs`foo`的开销是相同的 - 符号被评估.(def foo +)不包装`+`,它计算`+`,然后将该函数绑定到`foo`.两种情况都有一个函数调用.不需要宏. (4认同)