2010-10-25 9 views
14

En la respuesta aceptada a otra pregunta, Setting Clojure "constants" at runtime se usa la función clojure constantly.Cuándo usar `constantemente` en clojure, ¿cómo y cuándo se evalúan sus argumentos?

La definición de constantly se ve así:

(defn constantly 
    "Returns a function that takes any number of arguments and returns x." 
    {:added "1.0"} 
    [x] (fn [& args] x)) 

La cadena de documentación dice lo que hace, pero no por eso que uno usaría.

En la respuesta dada en la pregunta anterior constantemente se utiliza como sigue:

(declare version) 

(defn -main 
    [& args] 
(alter-var-root #'version (constantly (-> ...))) 
(do-stuff)) 

Por lo tanto la función que devuelve constantemente se evalúa directamente por su resultado. Estoy confundido en cuanto a cómo esto es útil. Probablemente no entiendo cómo se evaluaría x con y sin estar envuelto en 'constantemente'.

¿Cuándo debo usar constantly y por qué es necesario?

Respuesta

10

La función constantly es útil cuando una API espera una función y solo quiere una constante. Este es el caso en el ejemplo proporcionado en la pregunta.

La mayoría de las funciones de alter-* (incluyendo alter-var-root) toman una función, para permitir que la persona que llama modifique algo en función de su valor anterior. Incluso si solo quiere que el nuevo valor sea 7 (sin tener en cuenta el valor anterior), aún necesita proporcionar una función (con solo 7 resultará en un intento de evaluarlo, lo cual fallará). Por lo tanto, debe proporcionar una función que simplemente devuelva 7. (constantly 7) produce solo esta función, ahorrando el esfuerzo requerido para definirla.

Editar: En cuanto a la segunda parte de la pregunta, constantly es una función normal, por lo que su argumento se evalúa antes de que se construya la función constante. Por lo tanto, (constantly @myref) siempre devuelve el valor al que hace referencia myref en el momento en que se llamó a constantly, incluso si se cambia posteriormente.

Cuestiones relacionadas