Помните, что Задержки запоминаются, поэтому последовательные вызовы с задержкой ваших адресов всегда будут давать тот же адрес, что и при первой отмене задержки.
(defn addresses [person-id]
{:home (str (rand-int 100) " Cool St.") :work "1243 Boring St."})
(defn person [id]
(merge {:addresses (delay (addresses id))} {:name "john"}))
(let [person1 (person 1)]
(println @(:addresses person1))
(println @(:addresses person1)))
При этом будет напечатано:
{:home 65 Cool St., :work 1243 Boring St.}
{:home 65 Cool St., :work 1243 Boring St.}
Обратите внимание, что домашний адрес не изменяется во второй раз задержке.
Если вы не хотите этого поведения, вам нужно вместо этого использовать закрытие функции.
(defn addresses [person-id]
{:home (str (rand-int 100) " Cool St.") :work "1243 Boring St."})
(defn person [id]
(merge {:addresses (fn [] (addresses id))} {:name "john"}))
(let [person1 (person 1)]
(println ((:addresses person1)))
(println ((:addresses person1))))
Это напечатает:
{:home 16 Cool St., :work 1243 Boring St.}
{:home 31 Cool St., :work 1243 Boring St.}
Обратите внимание, как домашний адрес отличался при последующем вызове на закрытие.
Итак, если вы addresses
, функция имеет побочный эффектскажем, выбирает адреса из базы данных.И люди могут поменять свои адреса, и вы бы хотели, чтобы ваш код всегда имел самый последний адрес, об этом следует помнить, если у вас работает Delay или если лучшим вариантом будет закрытие функции.