Clojure无限循环

21

如何以惯用方式创建一个无限循环?


while(true){
   calc();
}

我希望永远调用calc函数。只需一次调用该函数即可。

编辑: 我忘了提到另一件事,那就是calc有副作用。它进行一些计算并修改一个字节数组。

4个回答

28

while 是核心库中的一部分。

(while true (calc))

这会扩展为一个简单的recur

(defmacro while
  "Repeatedly executes body while test expression is true. Presumes
  some side-effect will cause test to become false/nil. Returns nil"
  [test & body]
  `(loop []
     (when ~test
       ~@body
       (recur))))

2
似乎 (while (calc) nil) 更有用。 - Kzqai

17

使用 while 宏,可以像 Brian 在他的回答中提供的那样,很容易编写一个只是从 while 中删除布尔测试的 forever 宏:

(defmacro forever [& body] 
  `(while true ~@body))

user=> (forever (print "hi "))                         
hi hi hi hi hi hi hi hi hi hi hi ....

这就是 Lisp 的有趣之处,您可以创建自己的控制结构,以便避免大量的 样板代码


有了while循环,编写一个做完全相同事情的forever宏就有点毫无意义了。除非你想要澄清名称,在这种情况下,也许应该有人编写一个函数同义词宏! :p - Rayne
3
我不同意。你认为 dosync 没有意义吗?你可以写成 (sync nil ...) 的形式。 - Jonas

13

(循环 [] (计算) (递归))


这是简单尾递归的语法,我一时想不起来。 - Steve Gilham

3

另一种解决方案是使用repeatedly,如下所示:

(repeatedly calc)

与无限循环不同,这将返回一个无限序列。虽然惰性序列会比紧密循环慢一些,但也允许对循环进行一定的控制。


2
这将产生一个惰性序列,因此副作用可能不会被执行。因此答案应包括“doall”。 - Roman Smelyansky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接