为什么Clojure的每次通话都会增加三个gensym?

时间:2014-05-11 17:58:34

标签: clojure

lisps相当新,但在查看顺序整数生成代码时,我注意到重复调用(gensym)会使前缀后面提供的数字增加3.我很好奇为什么会这样。< / p>

user=> (gensym)
G__662
user=> (gensym)
G__665
user=> (gensym)
G__668
user=> (gensym)
G__671
user=> (gensym)
G__674
user=> (gensym)
G__677

我已经看到并理解atominc的综合使用,但我是gensym函数的新手。

2 个答案:

答案 0 :(得分:12)

这里有很多正确答案。一个是:它没有!

user> (take 5 (repeatedly gensym))
(G__2173 G__2174 G__2175 G__2176 G__2177)

另一个原因是:gensym没有对它产生的符号形式作出任何保证,所以你真的不应该关心它们是否顺序(或者即使它们包含数字)在所有)。你当然不应该劫持gensym来产生一个整数序列。

最后:为什么在你的例子中它增加了三个?因为每次在repl中评估表单时,编译器都必须创建自己的一些gensyms。显然,对于(gensym)形式,它需要创建的数字是两个。

答案 1 :(得分:3)

它没有!

=> (str (gensym) (gensym))
"G__4027G__4028"

看看gensym的来源,我们可以看到它使用了clojure.lang.RT / nextID。

(defn gensym
  ([prefix-string] (. clojure.lang.Symbol (intern (str prefix-string (str (. clojure.lang.RT (nextID))))))))

nextID函数也用在LispReader中。因此,当您反复评估(gensym)时,读者可能正在使用两个ID。

我显然在我的过程中还有其他事情发生,好像我在评估之间等待任何时间,消耗更多的ID并且gensym间隙超过3。

https://github.com/clojure/clojure/search?q=nextid