Как я могу оценить список (нечистых) функций в 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
Это будет с нетерпением потреблять всю последовательность, вызывая все функции для побочных эффектов и возвращая все, что возвращает последняя из них:
(reduce #(%2) nil [#(println :foo) #(println :bar)])
; => prints :foo, then :bar, then returns nil
Если вы хотите сохранить возвращаемые значения, вы можете вместо этого использовать сокращения
:
(reductions #(%2) nil [#(println :foo) #(println :bar)])
; => prints :foo, then :bar, then returns (nil nil)
сокращений
можно найти в clojure.contrib.seq-utils
в Clojure 1.1 и в clojure.core
в текущих снимках состояния 1.2.
Обновление: Обратите внимание, что reductions
возвращает ленивую последовательность, поэтому это не улучшение по сравнению с map
(NB. В map
вы бы хотели используйте # (%)
вместо # (% 2)
). Я упомянул это здесь в основном для полноты картины. Фактически, я опубликовал весь ответ для полноты, потому что обычно я использовал подход Doseq
(см. Ответ Брайана).