2016-01-17 4 views
0

У меня есть последовательность функций (которые мутируют некоторые объекты) Я хотел бы выполнить, который работает, если я делаю это:Clojure: Как выполнить последовательность функций?

(foo1) 
(foo2) 
(foo3) 

Однако, я хочу, чтобы поместить этот код в функции, так что я могу выполнить эту последовательность, когда захочу. Если я делаю это:

(defn run-foos [] (do (foo1) (foo2) (foo3))) 

Мутации, созданные run-foos не то же самое, как 3 отдельных заявлениями ранее. Я прошу прощения, что я не могу кратко суммировать поведение моей программы здесь, но в основном я вижу, что существуют некоторые поведенческие различия между первой и второй версиями вышеприведенного кода.

То, что я хочу сделать, это есть функция run-foos, который будет выполнять foo1, foo2 и foo3, который работает так же, как я назвал каждый по отдельности в ряд. Как я могу это сделать?

+0

«Я вижу, что некоторые поведенческие различия между первыми и вторыми версиями коды выше.» Пожалуйста, будьте более конкретными в отношении различий. Как бы то ни было, ** вы не предоставили нам достаточно информации ** для оказания нам полезной помощи. – WolfeFan

ответ

3

Не видя остальной части вашего кода, разница здесь не очевидна (в общем, две одинаковые).

Единственная причина должна быть любой разница между двумя частями кода у вас есть, если первый был введен в РЕПЛ и foo1 или foo2 вернулся ленивый результат какой-то. В этом случае реплика заставит ленивый результат при печати, а run-foos - нет.

Если это ваша проблема, тогда было бы лучше продолжать использовать run-foos, но реорганизуйте свои другие функции, чтобы они не смешивали побочные эффекты и лень.

0

Этот вариант будет работать только с изменяемыми данными.

(defn run-foos [] (do (foo1) (foo2) (foo3))) 

Но стандартные структуры данных clojure неизменяемы. Таким образом, каждый раз, когда ваши данные проходят сквозную функцию независимо, функции будут работать с данными по умолчанию, которые без мутаций по функциям. Кроме того, run-foos будет возвращать данные только из последнего выражения, то есть (foo3).

«Значения всех, но последнее выражение отбрасывается, хотя происходят их побочные эффекты.» (Эмерик, Carper, Гранд: Clojure программирование, 2012)

Я думаю, что вам нужен потокобезопасность макрос:

(-> data 
    foo1 
    foo2 
    foo3) 

В процессе компиляции он расширяется до (foo3 (foo2 (foo1 data))). Данные передаются в функции по цепочке, и вы получите то, что хотите.

Чтобы прочитать о -> макросъемке с примерами здесь: https://clojuredocs.org/clojure.core/-%3E

Смежные вопросы