Remember that Delays are memoized, so successive calls of your addresses delay will always yield the same address as the first time you derefed the Delay.
(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)))
This will print:
{:home 65 Cool St., :work 1243 Boring St.}
{:home 65 Cool St., :work 1243 Boring St.}
Notice how the home address is unchanged on the second deref of the delay.
If you don't want this behavior you need to use a function closure instead.
(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))))
This will print:
{:home 16 Cool St., :work 1243 Boring St.}
{:home 31 Cool St., :work 1243 Boring St.}
Notice how the home address was different on the sub-sequent call to the closure.
So, if you're addresses function does side-effect, say fetches addresses from a database. And the persons can change their addresses, and you'd want your code to always have the most recent address, it's something to keep in mind if Delay works for you, or if a function closure would be a better candidate.