How to evaluate a sequence of impure functions in Clojure?

白昼怎懂夜的黑 提交于 2019-12-30 17:22:09

问题


How can I evaluate a list of (impure) functions in Clojure? For instance:

[#(println "1") #(println "2") #(println "3")]

The expected output is:

1
2
3

Is there a way to achieve this without using macros? Something like (map evaluate fns-seq), maybe?

(I need this for drawing some graphics using the Clojure.processing API.)


回答1:


user> (let [fs [#(println "1") #(println "2") #(println "3")]]
         (doseq [f fs] (f)))
1
2
3
nil



回答2:


This will eagerly consume the whole seq, calling all functions for side effects and returning whatever the last one returns:

(reduce #(%2) nil [#(println :foo) #(println :bar)])
; => prints :foo, then :bar, then returns nil

If you want to hold onto the return values, you can use reductions instead:

(reductions #(%2) nil [#(println :foo) #(println :bar)])
; => prints :foo, then :bar, then returns (nil nil)

reductions is found in clojure.contrib.seq-utils in Clojure 1.1 and in clojure.core in current snapshots of 1.2.

Update: Note that reductions returns a lazy seq, so it's no improvement over map (NB. in map you'd want to use #(%) rather than #(%2)). I mentioned it here mostly for completeness. In fact, I posted the whole answer for completeness, because normally I'd go with the doseq approach (see Brian's answer).




回答3:


(apply pcalls [#(println "1") #(println "2") #(println "3")]) does just that. Just be wary of pcalls' parallelism (therefore lack of sequentiality) and lazyness.




回答4:


An old question, I know, but there's another option. You could simply invoke the functions:

(defn generate-fns [] 
   [#(println "1") #(println "2") #(println "3")]) 

(dorun (pmap (memfn invoke) (generate-fns)))

This allows you to decide in a different context how you would like to execute the functions (say, pmap, or claypoole's upmap for example)



来源:https://stackoverflow.com/questions/3088831/how-to-evaluate-a-sequence-of-impure-functions-in-clojure

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!