¿Cómo realizo una función con efectos secundarios sobre un vector?
-
02-01-2020 - |
Pregunta
El saludo en primera persona funciona bien, ¿por qué no saludar a todos?
(defpartial greeting [name] [:p.alert "Hello " name ", how are you?"]) (defn say-hello [name] (append $content (greeting name))) (defn say-hello-to-first-person [names] (say-hello (first names))) (defn say-hello-to-everyone [names] (map say-hello names)) (say-hello-to-first-person ["Chris" "Tom" "Jim" "Rocky"]) (say-hello-to-everyone ["Chris" "Tom" "Jim" "Rocky"])
Solución
Quieres doseq
, "foreach" de Clojure:
(doseq [name names]
(say-hello name))
map
no funciona porque produce una secuencia diferida:Hasta que acceda a los elementos de la secuencia (lo cual no hace aquí), ninguno de ellos será evaluado y no se producirán efectos secundarios.
Otra opción es forzar la evaluación ajustando dorun
alrededor de map
.Pensar en por qué esto funciona puede ayudarle a comprender (aunque doseq
es el enfoque idiomático aquí).
Otros consejos
Como dice @edbond en su comentario, el mapa FN no evalúe hasta el momento necesario porque el mapa FN devuelve un SEC perezoso.
Este es el documento de Mapa fn Devuelve una secuencia perezosa que consiste en el resultado de aplicar F a la Conjunto de los primeros elementos de cada Coll, seguido de aplicando F al conjunto de segundo artículo en cada colo, hasta cualquiera de los Colls es exhausto.Cualquier artículo restante en otros Colls se ignoran.Función F debería aceptar argumentos del número de Colls.
Si necesita asegurarse de que los valores se evalúen en una parte específica de su código, puede usar doall o dorun