Convenciones de nombres
- permanecer en minúsculas para las funciones
use -
para la separación silábica (lo que sería un guión bajo o un caso de camello en otros idiomas).
(defn add-one
[i]
(inc i))
Los predicados (es decir, las funciones que devuelven verdadero o falso) terminan con ?
Ejemplos:odd?
even?
nil?
empty?
Los procedimientos de cambio de estado terminan en !
. Te acuerdas set!
verdad? oswap!
Elija longitudes cortas de nombres variables según su alcance. Eso significa que si tiene una variable auxiliar realmente pequeña, a menudo puede usar un nombre de una letra. (map (fn [[k v]] (inc v)) {:test 4 :blub 5})
elija nombres de variables más largos según sea necesario, especialmente si se usan para muchas líneas de código y no puede adivinar de inmediato su propósito. (mi opinión).
Siento que muchos programadores de clojure tienden a usar nombres genéricos y cortos. Pero, por supuesto, esto no es realmente una observación objetiva. El punto es que muchas funciones de clojure son en realidad bastante genéricas.
Funciones lambda
En realidad, puede nombrar funciones lambda. Esto es conveniente para depurar y perfilar (mi experiencia aquí es con ClojureScript).
(fn square-em [[k v]] {k (* v v)})
Utilice las funciones lambda en línea #()
como sea conveniente
Espacio en blanco
No debe haber líneas solo para padres. Es decir, cerrar los paréntesis de inmediato. Recuerde que los parens están ahí para el editor y el compilador, la sangría es para usted.
Las listas de parámetros de funciones van a una nueva línea
(defn contras
[ab]
(lista ab))
Esto tiene sentido si piensas en las cadenas de documentos. Están entre el nombre de la función y los parámetros. La siguiente cadena de documentos probablemente no sea la más sabia;)
(defn contras
"Emparejar cosas"
[ab]
(lista ab))
- Los datos emparejados se pueden separar por una nueva línea siempre que conserve el emparejamiento
(defn f
[{x: x
y: y
z: z
[abc]: coll}]
(imprimir x "" y "" z "" a "" b "" c))
(También puedes ingresar ,
como quieras pero esto se siente incómodo).
Para la sangría, use un editor suficientemente bueno. Hace años, esto era emacs para la edición lisp, vim también es genial hoy. Los IDE de clojure típicos también deberían proporcionar esta funcionalidad. Simplemente no use un editor de texto aleatorio.
En vim en modo comando, puede usar el =
comando para sangrar correctamente.
Si el comando se alarga demasiado (anidado, etc.), puede insertar una nueva línea después del primer argumento. Ahora el siguiente código no tiene mucho sentido, pero ilustra cómo puedes agrupar y sangrar expresiones:
(+ (if-let [age (: personal-age coll)]
(si (> 18 años)
años
0))
(cuenta (rango (- 3 b)
(reducir +
(rango b 10)))))
Una buena sangría significa que no tiene que contar los corchetes. Los corchetes son para la computadora (para interpretar el código fuente y sangrarlo). La sangría es para su fácil comprensión.
Funciones de orden superior vs. for
y doseq
formas
Viniendo de un fondo de Scheme, estaba bastante orgulloso de haber entendido map
y funciones lambda, etc. Muy a menudo, escribía algo como esto
(map (fn [[k x]] (+ x (k data))) {:a 10 :b 20 :c 30})
Esto es bastante difícil de leer. La for
forma es mucho mejor:
(for [[k x] {:a 10 :b 20 :c30}]
(+ x (k data)))
`map tiene muchos usos y es realmente agradable si está utilizando funciones con nombre. Es decir
(map inc [12 30 10]
(map count [[10 20 23] [1 2 3 4 5] (range 5)])
Usar macros de subprocesos
Utilice las macros de subprocesos ->
y ->>
también doto
cuando corresponda.
El punto es que las macros de subprocesos hacen que el código fuente parezca más lineal que la composición de funciones. El siguiente fragmento de código es bastante ilegible sin la macro de subprocesos:
(f (g (h 3) 10) [10 3 2 3])
Comparar con
(->
(h 3)
(g 10)
(f [10 3 2 3]))
Al usar la macro de subprocesos, normalmente se puede evitar la introducción de variables temporales que solo se usan una vez.
Otras cosas
- Use docstrings
- mantener funciones cortas
- leer otro código de clojure