将clojure函数评估为引用形式

时间:2014-07-22 19:13:45

标签: list macros clojure clojurescript

我正在使用一个带参数的函数,如下所示:     (test-function '((gate 1) (gate 3) (gate 2)))

list参数可以包含任意数量的元素,其中每个元素的格式为(gate x),其中x可以是0到8之间的整数。我有一个函数generate-gate-list,生成随机长度(最多10个)和内容的列表,尽管它们总是如上所述。

生成门列表的示例输出:((gate 2))(())((gate 1) (gate 6))

我希望能够在generate-gate-list中嵌套test-function,以便我可以测试一堆随机生成的列表,而不事先生成它们。换句话说,我想要这样的事情:(test-function '(generate-gate-list))除了已经评估了generate-gate-list之外。我尝试过某种宏语法 - 引用和取消引用,但这会导致已解决的变量,如(user/gate 3),它会破坏测试功能。这是我的生成门列表代码:

(defn generate-gate-list []
  (map symbol (repeatedly (rand-int 10) #(random-gate))))

random-gate将门元素输出为字符串,即"(gate 3)""(gate 2)"

简而言之,我希望(test-function (something-here (generate-gate-list)))(test-function (modified-generate-gate-list))等同于(test-function '((gate 1) (gate 4) (gate 2)))或生成门列表的其他任意输出。谢谢!

1 个答案:

答案 0 :(得分:7)

引用生成文字列表

我相信你的困惑是认为引用是产生列表的唯一方法。虽然引用可以生成'((gate 1) (gate 2))中的文字列表,但您可能已经发现,列表中的任何内容都不会被评估。因此,您无法以这种方式生成随机列表,因为您的随机变量将不会被评估。

符号仅生成符号

在列表的文本表示中调用symbol"(门1)"正如您在generate-gate-list函数中所做的那样,不起作用。它会生成一个看起来像列表的符号,而不是列表。

user=> (type (symbol "(gate 1)"))
clojure.lang.Symbol

使用list

创建列表

如果要进行评估,即使用变量填充列表,请使用list功能。

user=> (list 'gate 1)
(gate 1)

user=> (list 'gate (rand-int 10))
(gate 2)

实施例

不知道你的test-function是什么,让我们这样做

(defn test-function 
  [gate-list]
  "Turn a list of (gate n) pairs into a list of gate numbers" 
  (map second gate-list))

user=> (test-function '((gate 1) (gate 2)))
(1 2)

(defn generate-gate-list []
  (repeatedly (rand-int 10) #(list 'gate (rand-int 10))))

user=> (def a-random-list (generate-gate-list))
#'user/a-random-list

user=> a-random-list
((gate 2) (gate 5) (gate 2) (gate 8) (gate 4))

user=> (test-function a-random-list)
(2 5 2 8 4)