Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros 将Clojure宏视为一个函数_Macros_Clojure - Fatal编程技术网

Macros 将Clojure宏视为一个函数

Macros 将Clojure宏视为一个函数,macros,clojure,Macros,Clojure,如何使Clojure宏充当函数,以便将其作为参数传递?我希望能以某种方式把它包装起来 我不希望包装版本的行为与原始宏完全相同(按名称调用与按值调用的不同),但它在一些情况下会很有用,因为这并不重要。有一个危险的、不推荐使用的宏,您永远不应该使用它:-P 如果我理解正确,您可以将其包装到函数中 将平方函数的这种(愚蠢的)实现看作一个宏: (defmacro square [x] (list * x x)) 如您所知,直接将其作为arg传递是行不通的: user=> (map squar

如何使Clojure宏充当函数,以便将其作为参数传递?我希望能以某种方式把它包装起来


我不希望包装版本的行为与原始宏完全相同(按名称调用与按值调用的不同),但它在一些情况下会很有用,因为这并不重要。

有一个危险的、不推荐使用的宏,您永远不应该使用它:-P


如果我理解正确,您可以将其包装到函数中

将平方函数的这种(愚蠢的)实现看作一个宏:

(defmacro square [x]
  (list * x x))
如您所知,直接将其作为arg传递是行不通的:

user=> (map square [1 2 3 4 5])
java.lang.Exception: Can't take value of a macro: #'user/square (NO_SOURCE_FILE:8)
但将其包装到函数中可以实现以下目的:

user=> (map #(square %) [1 2 3 4 5])
(1 4 9 16 25)
或者(更糟糕的是),您可以制作另一个宏来执行更通用的包装:

(defmacro make-fn [m] 
  `(fn [& args#] 
    (eval `(~'~m ~@args#))))

user=> (map (make-fn square) [1 2 3 4 5])
(1 4 9 16 25)

我会坚持使用普通的函数包装,并跳过最后一个hack!:)

对于疯狂宏make fn,下面的那一个怎么样? 它也应该起作用,希望更容易理解

(defmacro make-fn [m] 
 `(fn [& args#]
    (eval 
      (cons '~m args#))))

嗯,这不适用于变量宏:user=>(apply#(or%)[true-false-false])java.lang.IllegalArgumentException:传递给:user$eval3$fn(NO_-SOURCE_-FILE:0)的参数数目错误(3)3点:(1)解决此示例的最佳方法是
(某些标识[true-false])
,(2)如果您知道参数的数目并明确说明,它会起作用:
(apply#(或%1%2%3)[true-false-false])
,(3)hacky
使fn
工作:
(apply(make-fn或)[true-false-false])
Hm当我在Clojure 1.2中尝试此示例时,这会导致堆栈溢出:(apply macro或?[true-false-false]),呃,这是真的,问题在于apply宏ns中扩展的私有函数:它是过时clojure.core one的副本,如果用实际版本替换它,则差异很奇怪(rest[1])->(),(next[1])->nil。第一个是零?停止递归的as-guard谓词引发堆栈溢出。