He escrito un programa en clojure pero algunas de las funciones no tienen argumentos. ¿Cuáles serían las ventajas de codificar funciones como "def" en lugar de "defn" sin argumentos?Clojure def vs defn para una función sin argumentos
Respuesta
def
s se evalúan una sola vez mientras que defn
s (con o sin argumentos) se evalúan (ejecutan) cada vez que se llaman. Por lo tanto, si sus funciones siempre devuelven el mismo valor, puede cambiarlas a def
s, pero no de otra manera.
¡Ah, no sabía esto, me salvaste de algunos errores graves! Entonces, si hay una definición que accede a una referencia, ¿nunca se volverá a calcular? ¿Qué pasa si el archivo se vuelve a cargar? – Zubair
'def' se vuelve a evaluar cuando se vuelve a cargar el archivo. –
Me parece incorrecto decir que las formas 'defn' se reevalúan. Como se señala en otras respuestas, 'defn' se resuelve a' def' en el tiempo de expansión de la macro, y de hecho todos se evalúan solo una vez en el tiempo de carga del archivo. – skuro
(defn name ...) es simplemente una macro que se convierte en (def name (fn ...) de todos modos, no importa cuántos parámetros tenga. Así que es solo un atajo. Consulte (doc defn) para más detalles .
user=> (def t0 (System/currentTimeMillis))
user=> (defn t1 [] (System/currentTimeMillis))
user=> (t1)
1318408717941
user=> t0
1318408644243
user=> t0
1318408644243
user=> (t1)
1318408719361
gracias. Este ejemplo de código valía más que una descripción de 1000 palabras. – user693960
Para que nadie pierda este punto crucial: como el comentario de Roman Bataev implica, '(def t2 (fn [] (System/currentTimeMillis))) 'hará que' t2' se comporte como 't1'. – Mars
la forma especial def
crea una objeto Var identificado por un símbolo dado como primer argumento. la identificación se creó mediante la asociación del símbolo dado con un VAR en un mapa llamado espacio de nombres.
el Var tiene una referencia a algún valor, que co ULD ser expresado (entre otros):
como una forma constante, que siempre se evalúa a su propio valor:
(def x 1) x ; => 1 ; x holds a reference to a number 1
como una forma de función, que a primera se evalúa a su valor resultante:
(def x (+ 2 2)) x ; => 4 ; x holds a reference to a number 4
como una forma método Java, que en primero se evalúa a su valor resultante:
(def x (System/currentTimeMillis)) x ; => 1417811438904 ; x holds a reference to a number 1417811438904 x ; => 1417811438904 ; still the same number!
como una forma lambda (función anónima), que a primera se evalúa a un objeto de función:
(def x (fn [] (System/currentTimeMillis))) x ; => #<user$x [email protected]> (x) ; function form, function evaluated ; => 1417811438904 (x) ; function form, function evaluated ; => 1417812565866
Hay es una regla simple para todo lo anterior. En el caso de def
forma especial una expresión S dado como su segundo argumento es evaluado recursivamenteantes de que se cree el enlace, por lo que el Var resultante está vinculado al resultado de esta evaluación.
Incluso fn
se evalúa anteriormente, pero su valor resultante es un objeto de función que contiene un código. Este código se ejecutará (y evaluará) cada vez que se llame a la función. Es por eso que hay diferentes resultados.
La macro defn
es como def
pero internamente crea una función anónima y luego le une un objeto Var. Su segundo argumento se convierte en un cuerpo de esta función y no se evalúa de una manera "regular". También se podría decir que se evalúa pero como una forma lambda: el resultado de la evaluación es un objeto de función, no el resultado de un cálculo instantáneo.
por lo que escribir:
(defn fun [] 1)
es sinónimo de:
(def fun (fn [] 1))
- 1. Definición de función de Clojure integradas: def vs defn
- 2. def sin argumentos
- 3. Redefiniendo "def" en Clojure
- 4. Clojure, defn, defn-, públicas/privadas, incumplimientos
- 5. ¿Cuál es la razón detrás de usar def y defn en lugar de simplemente definir?
- 6. defn vs. let respecto a la descomposición
- 7. ¿Cómo podría escribir una macro "defn" en Clojure?
- 8. Ejecutando una función enlazada dinámicamente en Clojure
- 9. validación de argumentos numéricos en Clojure
- 10. Scala: 'foo def = {1}' vs 'foo def {1}'
- 11. Alinear una función con macros Clojure
- 12. ¿Cómo encuentro dinámicamente metadatos para una función de Clojure?
- 13. Clojure imprime una lista sin paréntesis?
- 14. argumentos de palabras clave Clojure
- 15. obtener un código de función de clojure
- 16. ¿Cómo puedo definir una función en Clojure?
- 17. una función de Fibonacci recursiva en Clojure
- 18. ** kwargs vs 10 argumentos en una función python?
- 19. ¿Es posible declarar una función sin argumentos pero luego pasar algunos argumentos a esa función sin aumentar la excepción?
- 20. argumentos de la macro en clojure
- 21. Macro Clojure que crea una función de orden superior desde una función
- 22. ¿Aplica el Combinador Y a una función recursiva con dos argumentos en Clojure?
- 23. ¿Debo usar una función o una macro para validar argumentos en Clojure?
- 24. ¿Hay una función que tome una lista de listas de argumentos y aplique cada lista a una función determinada?
- 25. Scala: definir los parámetros por defecto en una función (val) vs utilizando un método (DEF)
- 26. Cómo defnir una función de una cadena en Clojure?
- 27. Expandir un vector en los argumentos de una función
- 28. with-meta vs^{} - Clojure
- 29. C++ palabra clave explícita para la función sin argumentos
- 30. Argumentos de función múltiples tipos
Qué quiere decir '(def x (fn [] (algo)))' o '(def x (algo)) ' Son completamente diferentes, y la respuesta aceptada solo es correcta para la segunda interpretación. –
Supongo que la segunda intervención, pero es un buen punto! – Zubair