被 clojure 及其宏所吸引和新手,我为自己设定了编写一个宏的任务,该宏从诸如“abc”之类的字符列表中生成所有长度为“n”的字符串。所以对于 n=2,输出应该是“aa”“ab”“ac”“ba”“bb”“bc”“ca”“cb”“cc”。我从以下函数作为模板开始:(defn mkstr [nv] (for [ivjv] (str ij)))。for绑定中'v'的重复以及创建多少个变量应该是'n'的函数;在这种特定情况下:2。
在阅读了'quote''unquote'等之后,然后按照一个关于宏的优秀在线教程,经过反复试验和一些简单的运气,我设法产生了以下函数和宏,无论'的值是什么,它都能提供所需的输出n'。真正困难的部分是生成“for”绑定中所需的可变数量的代码。
(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#))))
现在我的“真正”问题或缺乏理解是为了获得输出我必须这样做:(eval(mkcoms len chars))。为什么这只能通过使用 'eval' 起作用?的确,它可以按原样使用,但感觉有些不对劲。