代码生成 – 在Clojure宏中控制符号生成 - 代码日志

代码生成 – 在Clojure宏中控制符号生成

我正在尝试(作为一个自学习练习)来创建一个Clojure宏,它将生成一个代码以将一个函数应用于一个整数序列,并且对结果进行求和。

f(0)f(1)f(2)f(3)

这是我的尝试:

(defmacro testsum [func n] 
  `(fn [x#] (+ ~@( map (fn [i] `(~func x#)) (range n)))))

然而,x#gensym似乎出了问题,我最终得到两个不同版本的x,因此该功能不起作用:

(macroexpand '(testsum inc 3))

得到:

(fn* ([x__809__auto__] 
  (clojure.core/+ 
    (inc x__808__auto__) 
    (inc x__808__auto__) 
    (inc x__808__auto__))))

这几乎是我想要的不同的809和808版本的x …..

我究竟做错了什么?我认为汽车发型是为了创造一个唯一的符号,正是这样的目的?有更好的做法吗?

foo#-style gensyms仅在其创建的语法引用内才有效。在你的代码中,两个x#被创建在不同的语法引用块中:

(defmacro testsum [func n] 
  `(fn [x#] (+ ~@( map (fn [i] `(~func x#)) (range n)))))
  ^- s-q1      ^-unquote       ^- s-q2

要解决这个问题,请使用显式(gensym)调用:

(defmacro testsum [func n]
  (let [x (gensym "x")]
    `(fn [~x] (+ ~@(map (fn [i] `(~func ~x)) (range n))))))

而宏扩展((macroexpand'(testsum inc 3))):

(fn* ([x4966] (clojure.core/+ (inc x4966) (inc x4966) (inc x4966))))
http://stackoverflow.com/questions/2840119/controlling-symbol-generation-in-clojure-macros

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:代码生成 – 在Clojure宏中控制符号生成