Intenté lo siguiente en Clojure, esperando que se devolviera la clase de una secuencia no perezosa:
(.getClass (doall (take 3 (repeatedly rand))))
Sin embargo, esto todavía regresa clojure.lang.LazySeq. Supongo que doallsí evalúa la secuencia completa, pero devuelve la secuencia original ya que sigue siendo útil para la memorización.
Entonces, ¿cuál es el medio idiomático de crear una secuencia no perezosa a partir de una perezosa?
clojure
lazy-evaluation
Tim Clemons
fuente
fuente

doall(vec (take 3 (repeatedly rand)))Respuestas:
doalles todo lo que necesitas. El hecho de que elseqtipo hasLazySeqno significa que tenga una evaluación pendiente. Los perezososseqalmacenan en caché sus resultados, por lo que todo lo que necesita hacer es caminar el perezososequna vez (como lodoallhace) para forzarlo todo y, por lo tanto, convertirlo en no perezoso.seqno no forzar la colección entera a ser evaluado.fuente
realized?.realizeoperación que coincidarealized?.contains?no importa si se dio cuenta de la secuencia perezosa o no, esto responde a la pregunta específica tal como se le preguntó, pero menos al título de la pregunta.Hasta cierto punto, se trata de una cuestión de taxonomía. una secuencia perezosa es solo un tipo de secuencia como lo es una lista, vector o mapa. Entonces, la respuesta es, por supuesto, "depende del tipo de secuencia no perezosa que desee obtener:
elija entre:
(doall ... )(apply list (my-lazy-seq)) OR (into () ...)(vec (my-lazy-seq))Puede tener cualquier tipo de secuencia que se adapte a sus necesidades.
fuente
(vec (my-lazy-seq))no es tan agradable en situaciones como las siguientes:(vec (json/parse-string "{\"foo\":\"bar\"}")) ;; => [["foo" "bar"]]Dado quecheshireelige producir una(json/parse-string)(json/parse-string-strict)Este tipo rico parece conocer su clojure y tiene toda la razón.
Pero creo que este fragmento de código, usando su ejemplo, podría ser un complemento útil para esta pregunta:
De hecho, el tipo no ha cambiado, pero la realización ha
fuente
realized?regresartrue. Por ejemplo(let [r (range) r? (realized? r)] (doall (take 1 r)) [r? (realized? r)]) => [false true][true true]Me encontré con esta publicación de este blog sobre
doallno ser recursivo. Por eso encontré que el primer comentario en la publicación hizo el truco. Algo parecido a:Encontré esto útil en una prueba unitaria en la que quería forzar la evaluación de algunas aplicaciones anidadas
mappara forzar una condición de error.fuente
fuente