Recuerde que los retrasos se memorizan, por lo que las llamadas sucesivas de su dirección demorarán siempre la misma dirección que la primera vez que eliminó el Retraso.
(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)))
Esto imprimirá:
{:home 65 Cool St., :work 1243 Boring St.}
{:home 65 Cool St., :work 1243 Boring St.}
Aviso cómo el domicilio no se ha modificado en el segundo DEREF de la demora.
Si no desea este comportamiento, debe usar un cierre de función.
(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))))
Esto imprimirá:
{:home 16 Cool St., :work 1243 Boring St.}
{:home 31 Cool St., :work 1243 Boring St.}
Note como la dirección de su casa era diferente en la llamada sub-secuente al cierre.
Por lo tanto, si su función es addresses
tiene un efecto secundario, por ejemplo, recupera las direcciones de una base de datos. Y las personas pueden cambiar sus direcciones, y usted querría que su código siempre tenga la dirección más reciente, es algo a tener en cuenta si Delay funciona para usted o si el cierre de una función sería un mejor candidato.
muchas gracias. Me preguntaba si esto podría hacerse transparente para que pueda ser evaluado la primera vez que se usa. En lugar de forzar manualmente la evaluación? – Surya
No lo creo. Clojure es explícito en la pereza y la fuerza, hasta donde yo sé. –
My lazymap [library] (http://bitbucket.org/kotarak/lazymap) hace exactamente eso. Proporciona drop-ins transparentes para todos los tipos de mapas, que calculan sus valores solo en caso de que realmente se recuperen. – kotarak