Fer*_*osg 1 functional-programming clojure clojure-repl
我是Clojure的新手,为了练习,我试图为半随机数应用一个简单的算法.
几天前,我读到了clojure文档中的循环,以及它们如何使用recur,所以我试着用这行代码编写一个循环:
(def numbers_semi_random
(fn []
(loop[Xn 4 count 0]
(while (and (not (= Xn m)) (< count m))
(println (mod (+ (* 5.0 Xn) 7.0) m))
(recur (mod (+ (* 5.0 Xn) 7.0) m) (inc count))
))))
Run Code Online (Sandbox Code Playgroud)
但是当我执行代码时,会显示此错误
CompilerException java.lang.UnsupportedOperationException: Can only recur from tail position, compiling
Run Code Online (Sandbox Code Playgroud)
发生了什么?recur是不是在功能的尾部?
似乎你的意图可能是通过使用when代替来实现的while(你的循环会继续打印更新值,Xn直到满足条件),但是要解释异常:
从编译器的角度来看,问题是虽然while表单确实处于相对于你的尾部位置loop,但是while宏的扩展是这样的,即while身体中没有任何东西相对于while表单处于尾部位置.(如果身体处于尾部位置while,那么它也会处于封闭的尾部位置loop.)
这样做的原因是while扩展到loop表达式并recur在用户提供的主体之后提供它自己:
(while test
body...)
;; expands to
(loop []
(when test
body...
(recur)))
Run Code Online (Sandbox Code Playgroud)
所以,如果你提供一个recur身体的一部分while,你得到的是
(loop []
(when test
...
(recur ...) ; from user code
(recur)))
Run Code Online (Sandbox Code Playgroud)
这里用户提供(recur ...)的不是关于它立即封闭的尾部位置loop,这是编译器抱怨的.