Re: how to define a variable of type collection to keep other functions.
Thanks Sean, indeed this help me a lot .. one question, beside that it's not indicated to define def inside of a defn, as you pointed before, if I have the bellow code: *( defn some-method[arg] (def thred (. Thread currentThred) (println on current thread thread use variable arg))* 'thred' - is only visible inside of some-methd, because is a little confuse for me your statement - *`def` and `defn` create global bindings - they are not variable assignments - and you don't want `def` nested into `defn`.* do you know why is more advantages to use *let *instead of *def *inside a *defn *? thanks Sorin On Saturday, May 24, 2014 2:04:55 AM UTC+3, Sean Corfield wrote: On May 23, 2014, at 2:19 AM, sorin cristea srncr...@gmail.comjavascript: wrote: Thank Philippe for your advices,I came from java environment and seems I still remain with some 'bad' habits. Coming from Java, the main thing to bear in mind in Clojure is that you do not have variables in the sense you are used to and you generally avoid loops in favor of operations on whole collections (such as map/reduce). `def` and `defn` create global bindings - they are not variable assignments - and you don't want `def` nested into `defn`. You can use `let` to create local bindings (again, not variables). Clojure has `future` built-in so you might consider something like this: (defn sample-fc [] (let [futures (repeatedly 3 (fn [] (future task result !!!)))] (doseq [f futures] (println (deref f) Or just: (defn sample-fc [] (doseq [f (repeatedly 3 (fn [] (future task result !!!)))] (println @f))) ;; @f is short for (deref f) `repeatedly` takes a count and a no-arg function and return a sequence of results of calling that function. Or if you want to see the results differ: (defn sample-fc [] (doseq [f (for [i (range 3)] (future (str task result i !!!)))] (println @f))) But all of these are still procedural in that they loop over the data and print results, rather than constructing data structures and transforming them (and ultimately printing the result). Consider: (defn make-tasks [inputs] (for [i inputs] (future (str task result i !!! (defn join-tasks [tasks] (clojure.string/join \n (map deref tasks))) (println (join-tasks (make-tasks (range 3 Here we've separated out task creation (based on a sequence of inputs), task completion (gathering the results as a single string), and printing the result. Note that `map` is lazy so the actual task completion - deref - is forced by joining the results together since that is an eager operation. At this point you could also do: (- (range 3) make-tasks join-tasks println) which makes the pipeline sequence of steps more obvious. Since we've broken things down into small steps - and I mentioned `map` being lazy - it's instructive to see what happens if we don't force the mapped sequence to be used: (do (map deref (make-tasks (range 3))) (println DONE)) This will just print DONE (and nil, the result of calling `println`) but the tasks will not even be created because nothing uses them. You can prove this to your self by adding a `println` inside the `future` call like this: (future (do (println RUNNING i) (str task result i !!!))) There are several ways to force the mapped sequence to be used (realized). You could wrap it in a call to `doall`: (do (doall (map deref (make-tasks (range 3 (println DONE)) This realizes the mapped sequence (but still throws away the result). You could use `dorun`: (do (dorun (map deref (make-tasks (range 3 (println DONE)) This realizes the mapped sequence and returns nil (which is then thrown away). Or you could use `mapv` which produces a vector and is not lazy: (do (mapv deref (make-tasks (range 3))) (println DONE)) Or you could simply loop over the tasks, calling deref and throwing the result away via `doseq` (which is why this is kind of procedural): (doseq [f (make-tasks (range 3))] (deref f)) `doseq` returns nil. Which you choose depends on what, if anything, you want to do with the result. Hope that helps? Sean Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- 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
Re: how to define a variable of type collection to keep other functions.
On Wed, May 28, 2014 at 12:56:43AM -0700, sorin cristea wrote: *( defn some-method[arg] (def thred (. Thread currentThred) (println on current thread thread use variable arg))* 'thred' - is only visible inside of some-methd, because is a little confuse for me your statement - *`def` and `defn` create global bindings - they are not variable assignments - and you don't want `def` nested into `defn`.* In this case your thred var is actually visible globally, not only in the function. For example: user= (defn a-function [arg] #_= (def b (+ arg 1)) #_= (/ b 2)) #'user/a-function user= (a-function 1) 1 user= b 2 user= (a-function 3) 2 user= b 4 user= (a-function 111) 56 user= b 112 See how the value for b keeps changing? It's because a-function is changing the *global* b value. Let's try with another function, using let instead: user= (defn another-function [arg] #_= (let [barg (+ arg 1)] #_= (/ barg 2))) #'user/another-function user= (another-function 1) 1 user= barg CompilerException java.lang.RuntimeException: Unable to resolve symbol: barg in this context, compiling:(NO_SOURCE_PATH:0:0) user= (another-function 3) 2 user= barg CompilerException java.lang.RuntimeException: Unable to resolve symbol: barg in this context, compiling:(NO_SOURCE_PATH:0:0) user= (another-function 111) 56 user= barg CompilerException java.lang.RuntimeException: Unable to resolve symbol: barg in this context, compiling:(NO_SOURCE_PATH:0:0) Here you can see that the local variable in the let, barg doesn't escape to the global scope. In fact, there is no global barg variable at all! It's completely contained within another-function now. This is why we use let instead of def. def creates a *global* var, which is then in the global scope. let allows us to introduce our own bindings for values within the current lexical scope. (There are some other differences between them, but this is the strongest argument for using let over def, I think.) Carlo signature.asc Description: Digital signature
how to define a variable of type collection to keep other functions.
Hi all, do you have any idea how I can define a variable, global or inside a function, used to store for example the FutureTask objects resulted from ExecutorService submit(fn) call,I want to put all futures in a collection and later call 'get' on each of them. bellow is a sample of that code: (defn sample-fc [] (def futures '()) (dotimes [i 3] (def f (. thread-pool (submit (fn [] (task result !!!) (cons f futures) ) shutdown the pool (. thread-pool shutdown) (. thread-pool awaitTermination (. Long MAX_VALUE) (. TimeUnit SECONDS)) go through all futures an call get on them (doseq [f futures] (println (. f get)) ) ) when I do 'dosync' futures collection is empty, even if (def f (. thread-pool (submit (fn [] (task result !!!) is a a non empty object of type FutureTask(java.util.concurrent package). Do you know how to define 'futures' variable such that to keep all returned future ? thanks, Sorin -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: how to define a variable of type collection to keep other functions.
Hello This is not written as functional code. You have to understand that : (cons f futures) creates a new version of futures with f in front of it and cons *returns it to you*. Put another way,* futures is not modified by cons*. In your dotimes construct, the consed value is lost each loop. Have a look at loop/recur, map, and reduce, these are the backbone functions when programming in clojure. Also, do not use (def) inside a function, this is ugly. use let to define local bindings instead. -- Philippe. On Fri, May 23, 2014 at 10:16 AM, sorin cristea srncris...@gmail.comwrote: Hi all, do you have any idea how I can define a variable, global or inside a function, used to store for example the FutureTask objects resulted from ExecutorService submit(fn) call,I want to put all futures in a collection and later call 'get' on each of them. bellow is a sample of that code: (defn sample-fc [] (def futures '()) (dotimes [i 3] (def f (. thread-pool (submit (fn [] (task result !!!) (cons f futures) ) shutdown the pool (. thread-pool shutdown) (. thread-pool awaitTermination (. Long MAX_VALUE) (. TimeUnit SECONDS)) go through all futures an call get on them (doseq [f futures] (println (. f get)) ) ) when I do 'dosync' futures collection is empty, even if (def f (. thread-pool (submit (fn [] (task result !!!) is a a non empty object of type FutureTask(java.util.concurrent package). Do you know how to define 'futures' variable such that to keep all returned future ? thanks, Sorin -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- Philippe -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: how to define a variable of type collection to keep other functions.
Thank Philippe for your advices,I came from java environment and seems I still remain with some 'bad' habits. On Friday, May 23, 2014 12:04:52 PM UTC+3, Philippe Guillebert wrote: Hello This is not written as functional code. You have to understand that : (cons f futures) creates a new version of futures with f in front of it and cons *returns it to you*. Put another way,* futures is not modified by cons*. In your dotimes construct, the consed value is lost each loop. Have a look at loop/recur, map, and reduce, these are the backbone functions when programming in clojure. Also, do not use (def) inside a function, this is ugly. use let to define local bindings instead. -- Philippe. On Fri, May 23, 2014 at 10:16 AM, sorin cristea srncr...@gmail.comjavascript: wrote: Hi all, do you have any idea how I can define a variable, global or inside a function, used to store for example the FutureTask objects resulted from ExecutorService submit(fn) call,I want to put all futures in a collection and later call 'get' on each of them. bellow is a sample of that code: (defn sample-fc [] (def futures '()) (dotimes [i 3] (def f (. thread-pool (submit (fn [] (task result !!!) (cons f futures) ) shutdown the pool (. thread-pool shutdown) (. thread-pool awaitTermination (. Long MAX_VALUE) (. TimeUnit SECONDS)) go through all futures an call get on them (doseq [f futures] (println (. f get)) ) ) when I do 'dosync' futures collection is empty, even if (def f (. thread-pool (submit (fn [] (task result !!!) is a a non empty object of type FutureTask(java.util.concurrent package). Do you know how to define 'futures' variable such that to keep all returned future ? thanks, Sorin -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/d/optout. -- Philippe -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: how to define a variable of type collection to keep other functions.
On May 23, 2014, at 2:19 AM, sorin cristea srncris...@gmail.com wrote: Thank Philippe for your advices,I came from java environment and seems I still remain with some 'bad' habits. Coming from Java, the main thing to bear in mind in Clojure is that you do not have variables in the sense you are used to and you generally avoid loops in favor of operations on whole collections (such as map/reduce). `def` and `defn` create global bindings - they are not variable assignments - and you don't want `def` nested into `defn`. You can use `let` to create local bindings (again, not variables). Clojure has `future` built-in so you might consider something like this: (defn sample-fc [] (let [futures (repeatedly 3 (fn [] (future task result !!!)))] (doseq [f futures] (println (deref f) Or just: (defn sample-fc [] (doseq [f (repeatedly 3 (fn [] (future task result !!!)))] (println @f))) ;; @f is short for (deref f) `repeatedly` takes a count and a no-arg function and return a sequence of results of calling that function. Or if you want to see the results differ: (defn sample-fc [] (doseq [f (for [i (range 3)] (future (str task result i !!!)))] (println @f))) But all of these are still procedural in that they loop over the data and print results, rather than constructing data structures and transforming them (and ultimately printing the result). Consider: (defn make-tasks [inputs] (for [i inputs] (future (str task result i !!! (defn join-tasks [tasks] (clojure.string/join \n (map deref tasks))) (println (join-tasks (make-tasks (range 3 Here we've separated out task creation (based on a sequence of inputs), task completion (gathering the results as a single string), and printing the result. Note that `map` is lazy so the actual task completion - deref - is forced by joining the results together since that is an eager operation. At this point you could also do: (- (range 3) make-tasks join-tasks println) which makes the pipeline sequence of steps more obvious. Since we've broken things down into small steps - and I mentioned `map` being lazy - it's instructive to see what happens if we don't force the mapped sequence to be used: (do (map deref (make-tasks (range 3))) (println DONE)) This will just print DONE (and nil, the result of calling `println`) but the tasks will not even be created because nothing uses them. You can prove this to your self by adding a `println` inside the `future` call like this: (future (do (println RUNNING i) (str task result i !!!))) There are several ways to force the mapped sequence to be used (realized). You could wrap it in a call to `doall`: (do (doall (map deref (make-tasks (range 3 (println DONE)) This realizes the mapped sequence (but still throws away the result). You could use `dorun`: (do (dorun (map deref (make-tasks (range 3 (println DONE)) This realizes the mapped sequence and returns nil (which is then thrown away). Or you could use `mapv` which produces a vector and is not lazy: (do (mapv deref (make-tasks (range 3))) (println DONE)) Or you could simply loop over the tasks, calling deref and throwing the result away via `doseq` (which is why this is kind of procedural): (doseq [f (make-tasks (range 3))] (deref f)) `doseq` returns nil. Which you choose depends on what, if anything, you want to do with the result. Hope that helps? Sean Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) signature.asc Description: Message signed with OpenPGP using GPGMail