小编juh*_*ovh的帖子

Clojure fn名称在提前编译时泄露到其范围之外

我想用fn生成命名函数并从宏返回它们,我尝试了以下示例:

(defmacro getfn
  [namestr children]
  `(fn fn-name# []
     (println "Recursing" ~namestr)
     (doall (map (fn [child#] (child#)) ~children))))

(def foo (getfn "foo" []))
(def bar (getfn "bar" [foo]))

(defn -main [& args]
  (bar))
Run Code Online (Sandbox Code Playgroud)

结果输出通常与预期一致:

Recursing bar
Recursing foo
Run Code Online (Sandbox Code Playgroud)

但是,当我运行此编译提前(AOT)时,我得到:

Recursing bar
Recursing bar
...
Recursing bar
Recursing bar
Exception in thread "main" java.lang.StackOverflowError
Run Code Online (Sandbox Code Playgroud)

我发现很奇怪bar不断调用自己而不是foo,唯一合理的原因是生成的符号fn-name#泄漏到其范围之外.这是Clojure中的错误还是预期的行为?

更新:为清楚起见,请注意删除fn-name#符号并使函数匿名修复此问题.但是,在我的实际代码中,我需要有时递归地调用它,因此命名它是必要的.

stack-overflow recursion clojure

5
推荐指数
1
解决办法
101
查看次数

标签 统计

clojure ×1

recursion ×1

stack-overflow ×1