I often write code that I just want to run in an infinite loop.  The
code generates lots of random things, and logs the interesting ones to
a file.

In Python, I'd write such code inside a try block that catches the
Ctrl-C exception.  So, when I want to use my computer for something
else, I just hit ctrl-C, and the finalizing code is executed and then
it exits.

There was a thread here a while back, suggesting a solution involving
a break-thread utility in clojure.contrib.repl-utils.  I've tried
this, but it didn't work well in my Clojure Box / Slime environment.
So I was looking for another way, and came up with this:

(def *halt* (ref false))

(defn infinite-loop []
  (loop []
      (when (not @*halt*)
          (do (blah) (recur)))))

(defn on-thread [f]
  (.start (Thread. f)))
(defn launch [] (dosync (ref-set *halt* false)) (infinite-loop))
(defn halt []
  (dosync (ref-set *halt* true)))

This way, I type (launch) from the REPL, and (halt) from the REPL to stop.

It works, but....

If I'm editing my code while it's running, and recompile the file, now
*halt* is bound to a new ref, and the new halt function sets this new
ref, not the old one that the running threads are checking.  I don't
honestly need to hot-compile, but the fact that hot compilation breaks
this approach suggests to me that it's not the right way to do things.

One possibility is (I think?) to change the def of *halt* to
(declare *halt*)
(when (not *halt*)
   (def *halt* (ref false)))

but that also strikes me as a bit ugly.

Is there a cleaner way?

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to