Re: working with agents and atoms - a beginner question

2010-06-17 Thread Ryan Waters
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

2010-06-16 Thread Ryan Waters
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

2010-06-16 Thread 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?

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

2010-06-16 Thread Ryan Waters
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

2010-06-16 Thread Meikel Brandmeyer
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

2010-06-16 Thread Christophe Grand
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

2010-06-16 Thread Meikel Brandmeyer
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

2010-06-15 Thread Ryan Waters
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

2010-06-15 Thread Shawn Hoover
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

2010-06-15 Thread Meikel Brandmeyer
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

2010-06-15 Thread Christophe Grand
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