22

What is the idiomatic way to create an infinite loop?


while(true){
   calc();
}

I want to call the calc function forever. Only one function is called over and over again.

EDIT: One other thing I forgot to mention is that calc has side effects. It does some calculations and modifies a byte array.

4 Answers 4

28

while is in the core libraries.

(while true (calc))

This expands to a simple 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))))
Sign up to request clarification or add additional context in comments.

1 Comment

Seems like (while (calc) nil) would be more useful.
17

Using the while macro that Brian provides in his answer it is a simple task to write a forever macro that does nothing but drops the boolean test from while:

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

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

This is the fun part of any Lisp, you can make your own control structures and in return you avoid a lot of boilerplate code.

2 Comments

With while around, it would be kind of pointless to write a forever macro that does the exact same thing. Unless you wanted clarification on the name, and in that case, maybe somebody should write a function synonym macro! :p
I don't agree. Do you consider dosync pointless? You could just as well write (sync nil ...).
14

(loop [] (calc) (recur))

1 Comment

This being the syntax for simple tail recursion which I could not immediately bring to mind.
2

Another solution would be to use repeatedly like:

(repeatedly calc)

Rather than an infinte loop, this returns an infinite sequence. The lazy sequence will be a little slower than a tight loop but allows for some control of the loop as well.

1 Comment

this will produce a lazy sequence as you said, so the side effects might not be executed. so the answer should include 'doall'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.