Re: working with agents and atoms - a beginner question
After reading your posts and thinking wouldn't it be nice to just kick off a thread and not care about the return value I recall Rich using/liking [1] the Java Executor framework [2]. I looked at clojure.lang.Agent and saw it used there, too. It's tricky because I wouldn't want to lean on Java too much for something this fundamental or go too far without expecting to have to code something as complicated as what's found in core.clj (with possible java mechanics as found in RT.java). I picture wanting a system that can kick off workers (Executor framework) that only needs start() and join() semantics. I haven't gone through all the Executor and related stuff yet so I still need to read about everything that's available. - - - [1] http://clojure.org/concurrent_programming [2] http://www.ibm.com/developerworks/java/library/j-jtp1126.html On Wed, Jun 16, 2010 at 3:51 PM, Meikel Brandmeyer m...@kotka.de wrote: Hi, Am 16.06.2010 um 22:34 schrieb Christophe Grand: I agree, it still feels a little dirty to use a future without caring about the return value but on the positive said you get an easy way to block and wait for the tread to finish (deref) and you also get future-done?, future-cancel and future-cancelled which can prove useful. True. This infrastructure is an incentive to use future. Maybe one can wash away the dirty feeling by believing, that deref'ing is actually a syncronisation point of sorts and the return value just a side-effect. Sincerely Meikel -- 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 Note that posts from new members are moderated - please be patient with your first post. 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 -- 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 Note that posts from new members are moderated - please be patient with your first post. 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
Re: working with agents and atoms - a beginner question
On Tue, Jun 15, 2010 at 12:23 PM, Shawn Hoover shawn.hoo...@gmail.com wrote: On Tue, Jun 15, 2010 at 12:01 PM, Ryan Waters ryan.or...@gmail.com wrote: I'm working with the code at the following gist and also pasted below: http://gist.github.com/421550 I'd like to have execution of a separate thread (agent) continue running until it sees the atom 'running' change to false. Unfortunately, the program doesn't return from the send-off but to my understanding it should. Why won't it return? I'm using clojure 1.1. TIA (ns nmanage) (def running (atom true)) (defn process [] (when @running (prn hi) (Thread/sleep 1000)) (recur)) ;;; (send-off (agent nil) (process)) (do (prn this won't print - execution doesn't make it this far) (Thread/sleep 2000) (reset! running false)) It looks like you're passing the result of calling (process) as an argument to send-off. Try just (send-off (agent nil) process) to pass the process fn as a value. Doh! I should have caught that : ) Thank you for your help! -- 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 Note that posts from new members are moderated - please be patient with your first post. 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
Re: working with agents and atoms - a beginner question
Thank you for pointing that out. I notice your style is similar to Rich's in his ant.clj [1] which seems like the kind of solution that might be used in other functional and/or lisp languages. Do you know if that's the case with self-calling functions and agents? However, isn't there more overhead with calls to send-off instead of recur? I understand functions sent to an agent will only run one at a time, fifo-style, but was under the impression *agent* was for the current main thread of the program. Does *agent* instead refer to whatever is the current thread in the function's runtime context? Hope that question makes sense. [1] http://clojure.googlegroups.com/web/ants.clj?gda=uyYClToAAADrLV-d6p24hYFcam_S99IgeBuuRL78NgAsI-ljfFHCWu9OU0NQiFWgQuhmPR7veGf97daDQaep90o7AOpSKHW0 On Tue, Jun 15, 2010 at 3:03 PM, Meikel Brandmeyer m...@kotka.de wrote: Hi, besides the answer you got from Shawn, I'd like to question your use of the agent system. This is not the way it is supposed to be used. To model a processing loop with agents you should send the action back to the agent itself. (def running? (atom true)) (defn process [agent-state step] (when @running? (send-off *agent* process (inc step))) (+ agent-state step)) (def a (agent 0)) (send-off a process 1) (Thread/sleep 100) (reset! running? false) Note: in an action *agent* refers to the current agent. Sincerely Meikel -- 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 Note that posts from new members are moderated - please be patient with your first post. 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
Re: working with agents and atoms - a beginner question
On Wed, Jun 16, 2010 at 12:17 AM, Christophe Grand christo...@cgrand.net wrote: Hi Ryan, On Tue, Jun 15, 2010 at 6:01 PM, Ryan Waters ryan.or...@gmail.com wrote: I'm working with the code at the following gist and also pasted below: http://gist.github.com/421550 I'd like to have execution of a separate thread (agent) continue running until it sees the atom 'running' change to false. Unfortunately, the program doesn't return from the send-off but to my understanding it should. Why won't it return? I'm using clojure 1.1. It does return from send-off -- in your gist's version at last thanks to Shawn but there are still other errors. (ns nmanage) (def running (atom true)) (defn process [] A fn sent as an action to an agent must accept at least one arg: the agent's current value (if additional args are passed to args, the action fn must accept them too). So the above line should be [_] (_ to signify that you don't care about the value) instead of [] Thank you - I was unaware that a function sent to an agent had to accept at least one arg. (when @running (prn hi) (Thread/sleep 1000)) (recur)) Here your recur is misplaced, you want to recur when @running is true so the (recur) should be at the end of the when form and it should have an extra argument since we changed process to take one arg. However this when/recur pattern is what the while macro expands to. (defn process [_] (while @running (prn hi) (Thread/sleep 1000))) Very true - in this example, I totally agree. The example I put together is a simplified version of the program I'm working on which uses some file I/O. I'm wanting to tail a file and process its contents over time so I had a loop that would read the file until it started reading 'nil', then sleep, then try again, creating a loop within a loop (and polling the file for new contents). In trying to keep the example program faithful to the other, I ended up with some nonsensical clojure ; ) ;;; (send-off (agent nil) (process)) Here it should be (send-off (agent nil) process) but Shawn already pointed this out. I think that using an agent and not caring about its value is kind of an abuse, better use a future. (def running (atom true)) (future (while @running (prn hi) (Thread/sleep 1000))) Here my near total ignorance of futures comes into play. Thank you very much for pointing this out as a better way. I've been so eager to write a first program in clojure that I haven't gotten through all the 1.1 (and 1.0) language features yet. :D ;;; (do (prn this prints now - fixed thanks to Shawn Hoover) (Thread/sleep 2000) (reset! running false)) hth, Christophe -- European Clojure Training Session: Brussels, 23-25/6 http://conj-labs.eu/ Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.cgrand.net/ (en) I appreciate yours and everyone's valuable time! -- 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 Note that posts from new members are moderated - please be patient with your first post. 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
Re: working with agents and atoms - a beginner question
Hi, Am 15.06.2010 um 23:27 schrieb Ryan Waters: Thank you for pointing that out. I notice your style is similar to Rich's in his ant.clj [1] which seems like the kind of solution that might be used in other functional and/or lisp languages. Do you know if that's the case with self-calling functions and agents? However, isn't there more overhead with calls to send-off instead of recur? Yes, there is additional overhead. However hijacking a thread from agent thread pool (even if send-off) is misusing agents as Christophe said. Agents is about updating states. Not about (long running) threads. The typical solution for your problem would probably be: (- long-running-function-with-recur Thread. .start) This starts you function in a dedicated thread and you can save the overhead of send-off and use recur directly. I'm unsure about using future here. For me future is a thing, which returns something. Using it for a process which does return something useful seems dirty to me. I understand functions sent to an agent will only run one at a time, fifo-style, but was under the impression *agent* was for the current main thread of the program. Does *agent* instead refer to whatever is the current thread in the function's runtime context? Hope that question makes sense. *agent* is bound to the agent whose action we are currently running in this thread. So concurrently running actions see different *agent*s. Hope this helps. Sincerely Meikel -- 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 Note that posts from new members are moderated - please be patient with your first post. 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
Re: working with agents and atoms - a beginner question
On Wed, Jun 16, 2010 at 10:20 PM, Meikel Brandmeyer m...@kotka.de wrote: The typical solution for your problem would probably be: (- long-running-function-with-recur Thread. .start) This starts you function in a dedicated thread and you can save the overhead of send-off and use recur directly. I'm unsure about using future here. For me future is a thing, which returns something. Using it for a process which does return something useful seems dirty to me. I agree, it still feels a little dirty to use a future without caring about the return value but on the positive said you get an easy way to block and wait for the tread to finish (deref) and you also get future-done?, future-cancel and future-cancelled which can prove useful. Christophe -- European Clojure Training Session: Brussels, 23-25/6 http://conj-labs.eu/ Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.cgrand.net/ (en) -- 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 Note that posts from new members are moderated - please be patient with your first post. 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
Re: working with agents and atoms - a beginner question
Hi, Am 16.06.2010 um 22:34 schrieb Christophe Grand: I agree, it still feels a little dirty to use a future without caring about the return value but on the positive said you get an easy way to block and wait for the tread to finish (deref) and you also get future-done?, future-cancel and future-cancelled which can prove useful. True. This infrastructure is an incentive to use future. Maybe one can wash away the dirty feeling by believing, that deref'ing is actually a syncronisation point of sorts and the return value just a side-effect. Sincerely Meikel -- 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 Note that posts from new members are moderated - please be patient with your first post. 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
working with agents and atoms - a beginner question
I'm working with the code at the following gist and also pasted below: http://gist.github.com/421550 I'd like to have execution of a separate thread (agent) continue running until it sees the atom 'running' change to false. Unfortunately, the program doesn't return from the send-off but to my understanding it should. Why won't it return? I'm using clojure 1.1. TIA (ns nmanage) (def running (atom true)) (defn process [] (when @running (prn hi) (Thread/sleep 1000)) (recur)) ;;; (send-off (agent nil) (process)) (do (prn this won't print - execution doesn't make it this far) (Thread/sleep 2000) (reset! running false)) -- 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 Note that posts from new members are moderated - please be patient with your first post. 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
Re: working with agents and atoms - a beginner question
On Tue, Jun 15, 2010 at 12:01 PM, Ryan Waters ryan.or...@gmail.com wrote: I'm working with the code at the following gist and also pasted below: http://gist.github.com/421550 I'd like to have execution of a separate thread (agent) continue running until it sees the atom 'running' change to false. Unfortunately, the program doesn't return from the send-off but to my understanding it should. Why won't it return? I'm using clojure 1.1. TIA (ns nmanage) (def running (atom true)) (defn process [] (when @running (prn hi) (Thread/sleep 1000)) (recur)) ;;; (send-off (agent nil) (process)) (do (prn this won't print - execution doesn't make it this far) (Thread/sleep 2000) (reset! running false)) It looks like you're passing the result of calling (process) as an argument to send-off. Try just (send-off (agent nil) process) to pass the process fn as a value. -- 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 Note that posts from new members are moderated - please be patient with your first post. 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
Re: working with agents and atoms - a beginner question
Hi, besides the answer you got from Shawn, I'd like to question your use of the agent system. This is not the way it is supposed to be used. To model a processing loop with agents you should send the action back to the agent itself. (def running? (atom true)) (defn process [agent-state step] (when @running? (send-off *agent* process (inc step))) (+ agent-state step)) (def a (agent 0)) (send-off a process 1) (Thread/sleep 100) (reset! running? false) Note: in an action *agent* refers to the current agent. Sincerely Meikel -- 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 Note that posts from new members are moderated - please be patient with your first post. 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
Re: working with agents and atoms - a beginner question
Hi Ryan, On Tue, Jun 15, 2010 at 6:01 PM, Ryan Waters ryan.or...@gmail.com wrote: I'm working with the code at the following gist and also pasted below: http://gist.github.com/421550 I'd like to have execution of a separate thread (agent) continue running until it sees the atom 'running' change to false. Unfortunately, the program doesn't return from the send-off but to my understanding it should. Why won't it return? I'm using clojure 1.1. It does return from send-off -- in your gist's version at last thanks to Shawn but there are still other errors. (ns nmanage) (def running (atom true)) (defn process [] A fn sent as an action to an agent must accept at least one arg: the agent's current value (if additional args are passed to args, the action fn must accept them too). So the above line should be [_] (_ to signify that you don't care about the value) instead of [] (when @running (prn hi) (Thread/sleep 1000)) (recur)) Here your recur is misplaced, you want to recur when @running is true so the (recur) should be at the end of the when form and it should have an extra argument since we changed process to take one arg. However this when/recur pattern is what the while macro expands to. (defn process [_] (while @running (prn hi) (Thread/sleep 1000))) ;;; (send-off (agent nil) (process)) Here it should be (send-off (agent nil) process) but Shawn already pointed this out. I think that using an agent and not caring about its value is kind of an abuse, better use a future. (def running (atom true)) (future (while @running (prn hi) (Thread/sleep 1000))) ;;; (do (prn this prints now - fixed thanks to Shawn Hoover) (Thread/sleep 2000) (reset! running false)) hth, Christophe -- European Clojure Training Session: Brussels, 23-25/6 http://conj-labs.eu/ Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.cgrand.net/ (en) -- 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 Note that posts from new members are moderated - please be patient with your first post. 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