Хорошо Вот что я пытаюсь сделать
(defn addresses [person-id]
;addresses-retrival )
(defn person [id]
(merge {:addresses (addresses id)} {:name "john"}))
В вышеупомянутой функции person я хочу, чтобы адреса были получены только по требованию, например, только когда я делаю
(:addresses (person 10))
, а не когда
(person 10)
Я не уверен, правильно ли я поступаю, будучи новичком в clojure.
Вы можете использовать задержку.
(defn person [id]
(delay {:addresses (addresses id) :name "john"}))
(человек 2) затем вернет задержку, ничего не оценивая. Чтобы получить доступ к содержимому и оценить отложенный объект, используйте force или deref (или @).
(:addresses @(person 5))
Как вариант, вы можете установить задержку только по адресу.
(defn person [id]
{:addresses (delay (addresses id)) :name "john"})
что может быть лучше в зависимости от вашей проблемы.
Это позволяет определить:
(defn get-address [person]
@(:address person))
Которая получит задержанный адрес и принудительно его обработает. (Принудительное вычисление означает первое вычисление и получение принудительного результата в любое другое время).
По крайней мере, в том, что касается последовательностей, clojure чертовски лениво, и не требует дополнительных указаний.
Здесь, моделируя получение адреса как подсчет, попробуйте:
(defn addresses [person-id]
(iterate #(do (println %) (inc %)) person-id))
(defn person [id]
(merge {:addresses (addresses id)} {:name "john"}))
(def people (map person (range 100)))
Пока что ничего не было напечатано, но если вы скажете:
(doall (take 5 (:addresses (nth people 10))))
Тогда вы должны увидеть, что печать происходит именно в тех случаях, когда это необходимо. приходится считать пять на десятом месте. Я полагаю, что это может быть именно то поведение, которое вы хотите?
Так что заставьте ваш поиск адреса производить ленивую последовательность (карта, фильтр, сокращение - все подойдет)
Я могу предложить что-то близкое к тому, что вы ожидаете.
; Note the use of anonymouns function. #(addresses id)
(defn person [id]
(merge {:addresses #(addresses id)} {:name "john"}))
; :addresses returns a function. Evaluate it by wrapping it in another set of parans.
((:addresses (person 10)))