Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.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
Clojure:为什么这个宏不工作?_Clojure_Macros - Fatal编程技术网

Clojure:为什么这个宏不工作?

Clojure:为什么这个宏不工作?,clojure,macros,Clojure,Macros,我正在用基本的例子探索宏,但我不明白它是如何工作的 这: (defmacro evalf [f v] (f v)) (evalf + 2) 不起作用 我试过: (defmacro evalf [f v] '(f v)) (evalf + 2) 没有运气 我不理解其他语法:~~~等等,但它们也不起作用。我看到符号f没有指向+但是我不知道说“取f的值,它是+” 你能说清楚吗? 提前感谢试试看 (defmacro evalf [f v] (list f v)) (evalf (par

我正在用基本的例子探索宏,但我不明白它是如何工作的

这:

(defmacro evalf [f v]
  (f v))
(evalf + 2)
不起作用

我试过:

(defmacro evalf [f v]
  '(f v))
(evalf + 2)
没有运气

我不理解其他语法:~~~等等,但它们也不起作用。我看到符号f没有指向+但是我不知道说“取f的值,它是+”

你能说清楚吗? 提前感谢

试试看

(defmacro evalf [f v]
  (list f v))

(evalf (partial * 2) 66); 132
在调用
evalf

  • 参数以未赋值的形式传递,如
    (partial*2)
    66
  • 宏的主体产生表达式
    (list'(partial*2)'66)
    • 其计算结果为形式
      ((部分*2)66)
    • 从宏返回的值计算为
      132
另一种方法是使用语法引用

(defmacro evalf [f v]
  `(~f ~v))
试一试

在调用
evalf

  • 参数以未赋值的形式传递,如
    (partial*2)
    66
  • 宏的主体产生表达式
    (list'(partial*2)'66)
    • 其计算结果为形式
      ((部分*2)66)
    • 从宏返回的值计算为
      132
另一种方法是使用语法引用

(defmacro evalf [f v]
  `(~f ~v))

根据您要执行的操作,有两种变体:

第一个(您可能想要的)是:

它们都做相同的事情:生成所需的s表达式。 有了这个
(evalf+10)
将在编译时扩展为
(+10)
,然后在运行时成功地进行评估

第二个是:

(defmacro evalf [f v] ((resolve f) v))
现在,函数
f
将在编译时调用,因此宏将扩展为结果:
10

您使用
(fv)
的变体以静默方式失败,因为当您调用
(evalf+10)
时, 这里的
+
只是一个简单的符号,而不是从宏的角度对函数的引用,因此它尝试调用
('+10)
,因为clojure中的符号具有函数的语义,它的语法是完全正确的,但此调用会产生
nil
。(符号调用的示例:
('+{'+10})
=>10)因此,如果要获取名为此符号的函数,必须解析它,如我的第二个示例所示


带有
'(f v)
的变量只是扩展到两个符号的列表:
'f
'v
,然后导致运行时调用
('f'v)
,该调用也返回
nil
,就像第一个变量一样。

根据您要执行的操作,有两个变量:

第一个(您可能想要的)是:

它们都做相同的事情:生成所需的s表达式。 有了这个
(evalf+10)
将在编译时扩展为
(+10)
,然后在运行时成功地进行评估

第二个是:

(defmacro evalf [f v] ((resolve f) v))
现在,函数
f
将在编译时调用,因此宏将扩展为结果:
10

您使用
(fv)
的变体以静默方式失败,因为当您调用
(evalf+10)
时, 这里的
+
只是一个简单的符号,而不是从宏的角度对函数的引用,因此它尝试调用
('+10)
,因为clojure中的符号具有函数的语义,它的语法是完全正确的,但此调用会产生
nil
。(符号调用的示例:
('+{'+10})
=>10)因此,如果要获取名为此符号的函数,必须解析它,如我的第二个示例所示


带有
'(f v)
的变量只是扩展到两个符号的列表:
'f
'v
,然后导致运行时调用
('f'v)
,它也返回
nil
,就像第一个变量一样。

谢谢,这两个都是答案,但我更理解你的答案,所以我选择了这个谢谢,这两个都是答案,但我更了解你的答案,所以我选择了这个