Clojure宏评估

标签 clojure macros eval

由于对 clojure 及其宏很感兴趣,我给自己设定了一个任务:编写一个宏,从字符列表(例如“abc”)生成所有长度为“n”的字符串。因此,对于 n=2,输出应为“aa”“ab”“ac”“ba”“bb”“bc”“ca”“cb”“cc”。我从以下函数作为模板开始: (defn mkstr [n v] (for [i v j v] (str i j)))。 for 绑定(bind)中“v”的重复以及多少个变量的创建应该是“n”的函数;在本例中:2.

在阅读了“quote”“unquote”等内容之后,然后遵循了有关宏的优秀在线教程,进行了多次尝试和错误,并且运气不错,我成功地生成了以下函数和宏,无论什么,它们都能提供所需的输出'n' 的值。真正困难的部分是生成“for”绑定(bind)中所需的可变数量的代码。

(defn mkvars [n] 
"Gives a list of 'n' unique symbols"
(let [vc (repeatedly n #(gensym ))] vc)) 

(defmacro mkcoms [n syms] 
"Generates a list of possible combinations of length 'n' from a string of symbols"
`(let [vs# (mkvars ~n) sy# ~syms  
    forarg# (vec (interleave vs# (repeat ~n sy#)))]
     `(for ~forarg# (str ~@vs#))))

现在我的“真正”问题或缺乏理解是为了获得输出我必须这样做: (评估(mkcoms len chars))。为什么这只能通过使用“eval”才能起作用?确实,它可以按原样使用,但感觉有些不对劲。

最佳答案

您的宏返回带引号的形式,这就是为什么当您将其传递给 eval 时它会起作用。我不明白宏相对于函数的目的是什么,所以我希望这个解释是您想要的。

宏应该生成它所代表的代码并返回它。您的宏生成一个引用的形式。如果您删除反引用的外层,这看起来是为了成为执行扩展的代码(宏)而不是结果代码的一部分,那么您确实可以在宏扩展时执行:

(defmacro mkcoms [n syms]                                                                                                      
  "Generates a list of possible combinations of length 'n' from a string of symbols"                                           
  (let [vs     (mkvars n)                                                                                                      
        sy     syms                                                                                                            
        forarg (vec (interleave vs (repeat n sy)))]                                                                            
    `(for ~forarg (str ~@vs))))

这听起来像是您所追求的,尽管我承认我不明白为什么您希望这种情况发生在“编译时”而不是运行时。

关于Clojure宏评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13660870/

相关文章:

macros - container_of宏的定义

testing - clojure.test 无法解析来自 `eval` 的符号。适用于 REPL 和 lein run

powershell - Clojure 已安装,但 clj 失败

clojure - Datomic中的SQL "limit"子句的等效项

c++ - 这两个 offsetof 宏有什么区别?

c - 让宏计算它的调用

matlab - 避免在 matlab 函数中求值

excel - 使用其他 Excel 单元格的字符串值表示公式中的 Excel 单元格地址?

variables - 将符号解析为宏与函数参数的规则是什么?

clojure - 构建 LISP 机器需要多少原语?十、七还是五?