Ответ 1
user> (let [fs [#(println "1") #(println "2") #(println "3")]]
(doseq [f fs] (f)))
1
2
3
nil
Как я могу оценить список (нечистых) функций в Clojure? Например:
[#(println "1") #(println "2") #(println "3")]
Ожидаемый результат:
1
2
3
Есть ли способ достичь этого без использования макросов? Что-то вроде (map evaluate fns-seq)
, может быть?
(Мне нужно это для рисования некоторых графических изображений с помощью API Clojure.processing.)
user> (let [fs [#(println "1") #(println "2") #(println "3")]]
(doseq [f fs] (f)))
1
2
3
nil
Это будет потреблять весь seq, вызывая все функции для побочных эффектов и возвращая все, что возвращается последним:
(reduce #(%2) nil [#(println :foo) #(println :bar)])
; => prints :foo, then :bar, then returns nil
Если вы хотите удержать возвращаемые значения, вы можете вместо этого использовать reductions
:
(reductions #(%2) nil [#(println :foo) #(println :bar)])
; => prints :foo, then :bar, then returns (nil nil)
reductions
находится в clojure.contrib.seq-utils
в Clojure 1.1 и в clojure.core
в текущих моментальных снимках 1.2.
Обновление: обратите внимание, что reductions
возвращает ленивый seq, поэтому он не улучшается по сравнению с map
(NB. в map
, который вы хотите использовать #(%)
, а не #(%2)
). Я упомянул об этом здесь в основном для полноты. Фактически, я опубликовал весь ответ для полноты, потому что обычно я бы пошел с подходом doseq
(см. Ответ Брайана).
(apply pcalls [#(println "1") #(println "2") #(println "3")])
делает именно это. Просто опасайтесь pcalls
'parallelism (следовательно, отсутствие последовательности) и ленивости.
Старый вопрос, я знаю, но есть другой вариант.
Вы могли бы просто invoke
выполнять следующие функции:
(defn generate-fns []
[#(println "1") #(println "2") #(println "3")])
(dorun (pmap (memfn invoke) (generate-fns)))
Это позволяет вам решить в другом контексте, как вы хотите выполнять функции (например, pmap
, или claypoole upmap
например)