2010-08-26 25 views
36

¿Cuáles son las mejores prácticas para definir constantes en Clojure en términos de estilo, convenciones, eficiencia, etc.Convenciones, estilo y uso de las constantes de Clojure?

Por ejemplo, ¿es así?

(def *PI* 3.14)

Preguntas:

caso de las constantes convertirse en capital en Clojure?

Estilísticamente, ¿deberían tener el carácter de asterisco (*) en uno o ambos lados?

¿Alguna consideración de eficiencia computacional que deba tener en cuenta?

+4

También recuerde que, sea lo que sea que termine por nombrarlo, puede que quiera darle metadatos const: '(def ^: const pi 3.14)' – jemmons

+0

Prefiero simplemente asumir que todo es una constante a menos que se especifique lo contrario, como https: //github.com/bbatsov/clojure-style-guide aconseja. – mk12

+0

parece que sería útil tener una forma de hacer algo constante para usos en cosas como declaraciones de casos, ¿no? – leeor

Respuesta

23

No creo que haya reglas duras y rápidas. Por lo general, no les doy ningún tratamiento especial en absoluto. En un lenguaje funcional, hay menos distinción entre una constante y cualquier otro valor, porque las cosas son más a menudo puras.

Los asteriscos en ambos lados se llaman "orejeras" en Clojure. Por lo general, se utilizan para indicar una var "especial" o una var que se rebote dinámicamente mediante el enlace posterior. Cosas como y en que ocasionalmente se repiten a diferentes flujos por los usuarios y estos son ejemplos.

Personalmente, simplemente lo llamaría pi. No creo que haya visto gente dando constantes nombres especiales en Clojure.

EDIT: Mister Carper acaba de señalar que él mismo capitaliza las constantes en su código porque es una convención en otros idiomas. Supongo que esto demuestra que hay al menos algunas personas que hacen eso.

Eché un vistazo rápido a través del coding standards pero no encontré nada al respecto. Esto me lleva a concluir que depende de usted si los capitaliza o no. No creo que nadie te abofeteará a la larga.

+1

Capitalizo mis constantes, porque es una convención común en otros idiomas. Ver también 'Math/PI' en Java. –

+1

Estoy seguro de que algunas personas lo hacen, al menos, pero no lo he visto en ningún código que haya visto hasta ahora. No creo que haya nada de eso en el núcleo tampoco. No parece ser parte de los http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards estándares de codificación, por lo que supongo que depende del individuo. – Rayne

+0

Sin embargo, uso mayúsculas para las definiciones de "tipo" (incluidas las estructuras) para crear un espacio de nombre convencional, separado para ellas (defstruct Foo: key1) – jneira

14

En el frente de eficiencia computacional, debe saber que no existe una constante global en Clojure. Lo que tienes arriba es una var, y cada vez que lo referencia, hace una búsqueda. Incluso si no se pone orejeras, los vars siempre se pueden rebotar, por lo que el valor siempre puede cambiar, por lo que siempre se levantan en una tabla. Para bucles críticos de rendimiento, esto es decididamente no óptimo.

Existen algunas opciones, como colocar un bloque de permiso alrededor de los bucles críticos y dejar el valor de cualquier valor "constante" para que no se busquen. O creando una macro sin arg para que el valor constante sea compilado en el código. O podría crear una clase Java con un miembro estático.

Ver este post, y la siguiente discusión acerca de constantes para obtener más información:

http://groups.google.com/group/clojure/msg/78abddaee41c1227

+0

Creo que "no existe algo así como una constante global en Clojure" es tan importante filosóficamente como lo es desde el punto de vista de la eficiencia. Dicho esto, la discusión vinculada es muy útil para dar un ejemplo práctico de lo que está sucediendo con los vars. –

+1

Hay, si agrega ^: const a Var va a alinear el Var, es decir, buscará el valor una vez cuando se cargue el espacio de nombres, y reemplazará todo usando el Var con el valor sí mismo. –

8

Las orejeras son una forma de denotar que un símbolo dado tendrá su propio local de subprocesos vinculante en algún punto. Como tal, no tiene sentido aplicar las orejeras a su Pi constante.

*clojure-version* es un ejemplo de una constante en Clojure, y está completamente en minúsculas.

+0

Sin embargo, no tiene sentido considerar '* clojure-version *' thread local. Parece que la convención orejeras no es tan específica como lo implica tu respuesta. –

+0

Aunque acabo de descubrir las convenciones de codificación de clojure http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards. Allí, el estilo de orejeras se especifica solo para las cosas que deberían rebotar. –

+4

Sí, enlace local de rebote/hilo. Pero ¿por qué * clojure-versión * se supone que es rebote está más allá de mí. – Anders

0

Según el libro "Practical Clojure", que debe ser nombrado *pi*

+1

¿Cuáles son sus argumentos? Las orejeras indican que el símbolo será rebote. – Anders

+1

Es para [Alabama] (http://www.snopes.com/religion/pi.asp). – Brigham

+0

De hecho, es para [Indiana] (http://en.wikipedia.org/wiki/Indiana_Pi_Bill). – Mars

39

De http://dev.clojure.org/display/community/Library+Coding+Standards:

Uso orejeras sólo para las cosas destinadas a la reconsolidación. No use una notación especial para constantes; todo se supone constante a menos que se especifique lo contrario.

+4

No hace falta decir que "No use una notación especial para las constantes" significa que debe evitar las mayúsculas ... pero lo dije de todos modos. – Corin

1

Clojure tiene una variedad de literales tales como:

3.14159 
:point 
{:x 0 
:y 1} 
[1 2 3 4] 
#{:a :b :c} 

Los literales son constantes. Hasta donde yo sé, no hay forma de definir nuevos literales. Si desea utilizar una nueva constante, puede generar efectivamente un literal en el código en tiempo de compilación:

(defmacro *PI* [] 3.14159265358979323) 
(prn (*PI*)) 
1

En Common Lisp, hay una convención de nombrar constantes con signos más (+my-constant+), y en el esquema, mediante un prefijo con un signo de dólar ($my-constant); ver this page. Cualquier convención de este tipo entra en conflicto con los estándares oficiales de codificación Clojure, vinculados en otras respuestas, pero tal vez sería razonable querer distinguir vars regulares de los definidos con el atributo :const.

Creo que hay una ventaja para dar a las variables no funcionales de cualquier tipo algún tipo de característica distintiva. Suponga que, aparte de las variables definidas para contener funciones, normalmente solo utiliza nombres locales definidos por parámetros de función, let, etc. Si de todos modos define ocasionalmente una variable no funcional usando def, cuando su nombre aparece en una definición de función en el mismo archivo, se ve a simple vista como una variable local. Si la función es compleja, puede pasar varios segundos buscando la definición del nombre dentro de la función. Agregar una característica distintiva como orejeras o signos más o mayúsculas, según corresponda al uso de la variable, hace que sea obvio que la definición de la variable está en otro lugar.

Además, hay buenas razones para dar constantes especiales como pi un nombre especial, por lo que nadie tiene que preguntarse si pi significa, por ejemplo, "índice de impresión", o la i-ésima pizza, o "interfaz preservada" ". Por supuesto, I creo que esas variables deberían tener nombres más informativos, pero muchas personas usan nombres crípticos de variables cortas y termino leyendo su código. No debería tener que preguntarme si pi significa pi, por lo que algo como PI podría tener sentido. Nadie pensaría que es una corrida de la variable del molino en Clojure.

Cuestiones relacionadas