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.com<javascript:>> > 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 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.