Uso muchos mapas y estructuras en mis programas de clojure. ¿Cuáles son los beneficios (aparte del rendimiento) de convertirlos en defregords?¿Dónde debo usar defrecord in clojure?
Respuesta
considero estructuras parece haber quedado demostrado de manera efectiva por lo que no usarlos en absoluto.
Cuando tengo un conjunto fijo de claves conocidas que se usan en muchas instancias de mapas, normalmente creo un registro. Las grandes ventajas son:
- Rendimiento
- clase generada tiene un tipo que pueda encender en métodos múltiples u otras situaciones
- Con macro maquinaria adicional alrededor defrecord, puedo conseguir la validación de campos, los valores por defecto, y cualquier otra cosa que quiero
- Los registros pueden implementar interfaces o protocolos arbitrarios (mapas) no pueden
- Records actuar como mapas para la mayoría de los propósitos
- llaves y Vals devuelven los resultados en estables (pe r-creación) para
Algunas desventajas de los registros:
- Debido a que los registros son instancias de clases Java (no mapas de Clojure), no existe un intercambio estructural por lo que la misma estructura de registro es probable que utilice más memoria que la estructura de mapa equivalente que se ha cambiado. También hay más creación/destrucción de objetos a medida que "cambia" un registro, aunque la JVM está diseñada específicamente para comer este tipo de basura de corta duración sin sudar.
- Si cambia los registros durante el desarrollo, probablemente necesite reiniciar su REPL con mayor frecuencia para recoger esos cambios. Por lo general, esto solo es un problema durante fragmentos pequeños de desarrollo.
- Muchas bibliotecas existentes no se han actualizado para admitir registros (postwalk, zip, matchure, etc, etc.). Hemos agregado este soporte según sea necesario.
Otra ventaja importante es que el registro tiene un tipo (su clase) que puede enviar fuera de.
Un ejemplo que utiliza esta característica, pero no es representativo de todos los usos posibles es la siguiente:
(defprotocol communicate
(verbalize [this]))
(defrecord Cat [hunger-level]
communicate
(verbalize [this]
(apply str (interpose " " (repeat hunger-level "meow")))))
(defrecord Dog [mood]
communicate
(verbalize [this]
(case mood
:happy "woof"
"arf")))
(verbalize (->Cat 3))
; => "meow meow meow"
(verbalize (->Dog :happy))
; => "woof"
No realmente, ya que puede enviar en cualquier función, no solo escribir. Puede usar un mapa ordinario y, por ejemplo, agregar otra entrada con una clave llamada "tipo". Luego puede usar una función de despacho que verifique el valor de la entrada "tipo". –
@Goran, que se aplica a multimétodos, mediante el uso de protocolos, solo puede enviar por tipo. A pesar de todo, mi punto era usar defrecords agrega un tipo implícitamente mientras que una defstruct o mapa no agrega automáticamente un tipo. – bmillare
Esta respuesta es muy escueta, un ejemplo podría ser una buena adición. – matanster
Stuart Sierra escribió recientemente un interesante artículo sobre "Resolver el Problema Expresión con Clojure 1.2", que también contiene una sección sobre defrecord
:
http://www.ibm.com/developerworks/java/library/j-clojure-protocols/index.html#datatypes
Creo que todo el artículo es un buen punto de partida punto para entender protocolos y registros.
Esta es una respuesta de solo enlace. Necesita al menos un resumen imo. – MasterMastic
Usa mapas en la mayoría de los casos y registra solo cuando requieras polimorfismo. Con los mapas solo, puede usar métodos multimétodos; sin embargo, necesita registros si quiere protocolos. Dado esto, espere hasta que necesite protocolos antes de recurrir a los registros. Hasta entonces, evítelos a favor de un código más centrado en los datos y más simple.
Además de lo que se ha señalado anteriormente, además de estar a la par o superior en términos de rendimiento y exponer la misma interfaz de programación como un mapa, los registros refuerzan la estructura: los nombres de las teclas y el número de claves se aplican en el momento de la definición. Esto podría ser útil para evitar errores tontos cuando se espera la misma estructura a partir de muchos valores (o de lo contrario es rígida artificialmente).
Sean cuales sean las motivaciones originales, esta propiedad también lo diferencia de los mapas.
- 1. clojure defrecord nombrado parámetros?
- 2. Combinando Clojure defprotocol y defrecord
- 3. ¿Cómo usar "Update-in" en Clojure?
- 4. ¿Cómo debo usar Properties in C#?
- 5. ¿Cómo escribo: else in condp in Clojure?
- 6. clojure REPL no detecta los cambios realizados en defrecord
- 7. ¿Macros recomendadas para agregar funcionalidad al constructor defrecord de Clojure?
- 8. Cuándo y dónde debo usar WCF
- 9. ¿Con qué frecuencia debo usar try and catch in C#?
- 10. Qué plug-in Mercurial debo usar para IntelliJ
- 11. ¿Para qué debo usar los dedos de Clojure?
- 12. Aplicación web Clojure: ¿dónde empiezo?
- 13. ¿Qué tiene de malo este uso de params de descanso con defprotocol y defrecord en Clojure?
- 14. ¿Debo implementar la interfaz Sec en clojure
- 15. ¿Cómo debo usar HTMLAgilityPack AppendNode?
- 16. OO Design in Rails: Dónde poner cosas
- 17. Usar Singleton In Interface Builder?
- 18. ¿Cuántas actividades debo usar?
- 19. ¿Debo usar HttpRuntime.Cache?
- 20. ¿Debo usar variables globales?
- 21. ¿Cuándo debo usar cuaterniones?
- 22. ¿Debo usar siempre genéricos?
- 23. ¿Cuándo debo usar adornos?
- 24. ¿Qué metainformaciones debo usar?
- 25. ¿Debo usar jQuery.each()?
- 26. ¿Qué DB debo usar?
- 27. debo usar RoutedEventHandler
- 28. ¿Debo usar claves externas?
- 29. ¿Debo usar Bootstrap?
- 30. ¿Debo usar autobox en Perl?
La forma de constructor que describe en su tercer argumento es a lo que se refiere Common Lisp como "Constructor BOA" - * por orden de argumento *, que se usa en tipos de concierto definidos con 'defstruct'. Consulte http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_b.htm#boa_lambda_list. – seh
Hola Alex: creo que verás que los registros sí utilizan el intercambio estructural bajo el capó: implementan una estructura de datos completa y persistente, por lo que mantienen todas las ventajas de los mapas regulares. – mikera
Mikera: un registro genera una clase Java con campos finales. Asociándose a uno debe generar un nuevo objeto Java. Puede reutilizar instancias de campo ya que son inmutables pero no es tan eficiente como un mapa Clojure normal. –