what the heck... mailing-list.print-from-threads> (Thread. ((constantly nil))) #<Thread Thread[Thread-100,5,main]> mailing-list.print-from-threads> (Thread. ((fn []))) #<Thread Thread[Thread-101,5,main]> mailing-list.print-from-threads> (Thread. ((fn [] nil))) #<Thread Thread[Thread-102,5,main]> mailing-list.print-from-threads> (Thread. (let [this-is-nil ((fn [] nil))] this-is-nil)) #<Thread Thread[Thread-103,5,main]> mailing-list.print-from-threads> (Thread. nil) ; Evaluation aborted. mailing-list.print-from-threads> (= nil (let [this-is-nil ((fn [] nil))] this-is-nil) ((fn [])) ((constantly nil))) true mailing-list.print-from-threads>
all of these things are referentially transparent, so how is clojure differentiating between things that evaluate to nil and nil itself? sincerely, --Robert McIntyre On Tue, Dec 28, 2010 at 2:29 AM, Robert McIntyre <r...@mit.edu> wrote: > Your problem is caused by one itty-bitty misplaced parenthesis that is > hard to catch; In your code which creates threads, you do: > > (.start (Thread. (#(sleeper-thread %1 %2 %3) out x (+ 2000 (rand-int > 5000))))))) > > #(sleeper-thread %1 %2 %3) is exactly the same as just sleeper-thread, > so this boils down to > > (.start (Thread. (sleeper-thread out x (+ 2000 (rand-int 5000))))))) > > and now you can see that you are evaulating your sleeper-thread > function before you actually create the thread. > > Thread wants Runnable object like a clojure function with no > arguments, so either > > (.start (Thread. #(sleeper-thread out x (+ 2000 (rand-int 5000))))))) > > or > > (.start (Thread. (partial sleeper-thread out x (+ 2000 (rand-int 5000))))))) > > would work and do what you expect. Here's a modified version of your > code with output: > > > > > > (ns mailing-list.print-from-threads) > > (defn sleeper-thread [out id t] > "Sleep for time T ms" > (binding [*out* out] > (let [start (System/nanoTime)] > (printf "%d sleeping for time %d\n" id t) > (Thread/sleep t) > (printf "%d slept for %d\n" id (int (/ (- (System/nanoTime) > start) 1e6)))))) > > (defn test-threads-rlm [n out] > (let [start (System/nanoTime)] > (dotimes [x n] > (.start (Thread. > (partial sleeper-thread out x (+ 2000 (rand-int > 5000)))))) > (println "Total time is:" (int (/ (- (System/nanoTime) start) > 1e6))))) > > > (defn test-threads [n out] > (let [start (System/nanoTime)] > (dotimes [x n] > (.start (Thread. > (#(sleeper-thread %1 %2 %3) out x (+ 2000 (rand-int > 5000)))))) > (println "Total time is:" (int (/ (- (System/nanoTime) start) > 1e6))))) > > > > mailing-list.print-from-threads> (test-threads-rlm 4 *out*) > 0 sleeping for time 6783 > 1 sleeping for time 3716 > 2 sleeping for time 6890 > Total time is: 2 > 3 sleeping for time 5582 > 1 slept for 3716 > 3 slept for 5582 > 0 slept for 6783 > 2 slept for 6890 > nil > mailing-list.print-from-threads> (test-threads 4 *out*) > 0 sleeping for time 5875 > 0 slept for 5875 > 1 sleeping for time 3413 > 1 slept for 3413 > 2 sleeping for time 3709 > 2 slept for 3710 > 3 sleeping for time 5483 > 3 slept for 5484 > Total time is: 18486 > nil > mailing-list.print-from-threads> > > > However, I am vexed at how your original code works at all! > > look at this! --- > > > ;;works > (Thread. (#(sleeper-thread %1 %2 %3) *out* 2 (+ 2000 (rand-int > 5000)))) > (= nil (#(sleeper-thread %1 %2 %3) *out* 2 (+ 2000 (rand-int 5000)))) > ;;true > > > ;;doesn't work > (Thread. nil) > > ;;works > (Thread. ((fn [a b c] (sleeper-thread a b c)) *out* 2 (+ 2000 > (rand-int 5000)))) > > ;;works > (Thread. ((fn []))) > > > How can you make a Thread with ((fn [])) > when (= ((fn [])) nil) ???? > > > sincerely, > > --Robert McIntyre > > > > > On Tue, Dec 28, 2010 at 1:45 AM, justinhj <justi...@gmail.com> wrote: >> On Dec 26, 11:42 pm, Alex Osborne <a...@meshy.org> wrote: >>> justinhj <justi...@gmail.com> writes: >>> > I tried passing *out* to my thread function and then binding it to >>> > *out* in the thread, and this works but then makes the threads execute >>> > one at a time, and I'm presuming that is because my use of *out* in >>> > the binding block is blocking for the other threads which use it. >>> >>> That doesn't sound right: binding itself never blocks. Can you post >>> some example code where you see this behaviour? >>> >>> As I understand it binding conveyance should happen automatically in the >>> upcoming 1.3 release (for futures and agents) but in 1.2 you can use >>> bound-fn, or for better performance use binding explicitly as you >>> suggested. >>> >>> (future-call (bound-fn [] (println "log..."))) >>> >>> (send some-agent (bound-fn [x] (println "log...") (inc x))) >> >> This is the code I've written so far >> >> (defn sleeper-thread [out id t] >> "Sleep for time T ms" >> (binding [*out* out] >> (printf "%d sleeping for time %d\n" id t) >> (Thread/sleep t) >> (printf "%d slept\n" id))) >> >> (defn test-threads [n out] >> (dotimes [x n] >> (.start (Thread. (#(sleeper-thread %1 %2 %3) out x (+ 2000 (rand- >> int 5000))))))) >> >> And the output is >> >> 0 sleeping for time 5480 >> 0 slept >> 1 sleeping for time 6739 >> 1 slept >> 2 sleeping for time 5444 >> 2 slept >> 3 sleeping for time 3087 >> 3 slept >> 4 sleeping for time 6753 >> 4 slept >> 5 sleeping for time 3489 >> 5 slept >> 6 sleeping for time 5864 >> 6 slept >> 7 sleeping for time 5523 >> 7 slept >> 8 sleeping for time 5659 >> 8 slept >> 9 sleeping for time 5052 >> 9 slept >> >> -- >> 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