Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Una guía de estilo para Clojure escrita por la comunidad

NotificationsYou must be signed in to change notification settings

jeko2000/clojure-style-guide

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 

Repository files navigation

Los models a seguir son importantes.
-- Oficial Alex J. Murphy / RoboCop

Esta guía de estilo para Clojure recomienda mejores practicas con elfin de que programadores de Clojure puedan desarrollar código quepueda ser mantenido por otros programadores del lenguaje. Una guía deestilo que refleja correctamente usos reales del lenguaje será usada.Mientras que una guía que trate de imponer un estilo rechazado poraquellos individuos a quién la guía trata de ayudar, está destinada aque nunca se use sin importar que tan buena sea.

Esta guía está separada en varias secciones de reglas relacionadas. Heintentado proveer razones fundamentales tras las reglas aquíexpuestas. Si es el caso de que la razón es omitida, es porque la heconsiderado evidente.

Cabe decir que estas reglas no salen de la nada. Las reglas son, en sugran mayoría basadas en mi extensiva carrera como ingeniero desoftware profesional, comentarios y sugerencias de miembros de lacomunidad de Clojure, y varios prestigiosos recursos de programaciónde Clojure tales como"Clojure Programming"y"The Joy of Clojure".

La guía es todavía un trabajo en progreso ya que algunas secciones aúnfaltan y otras están incompletas. Existen también unas reglas que sebeneficiarían de mejores ejemplos. A su debido tiempo, estos y otrosproblemas serán solucionados mas por ahora, vale la pena tenerlos enmente.

Ten en cuenta que la comunidad de desarrollo de Clojure tambiénmantiene una lista deestándares de código para librerías.

Tú tienes la opción de generar un archivo PDF o una copia HTML de estaguía usandoPandoc.

Traducciones de esta guía están disponibles en los siguientes idiomas:

Tabla de Contenido

Diseño y organización de código fuente

Casi todos están convencido que todos los estilos, salvo el suyo, esfeo e ilegible. Elimina "salvo el suyo" y probablemente estén en locorrecto...
-- Jerry Coffin (acerca de indentación/sangría)

  • Para indentación/sangría usaespacios y notabuladores.[link]

  • Usa 2 espacios de sangría en loscuerpos de formas con argumentos. Esto incluye todos las formasdef,formas especiales y macros que incluyen enlaces locales comoloop,let,when,cond,as->,cond->,case,with-*, etc.[link]

    ;; bueno(when algo  (algo-mas))(with-out-str  (println"Hola")  (println"mundo!"));; malo - cuatro espacios(when algo    (algo-mas));; malo - un solo espacio(with-out-str (println"Hola") (println"mundo!"))
  • Alinea verticalmenteargumentos de funciones o macros que abarcan múltiples líneas.[link]

    ;; bueno(filter even?        (range110));; malo(filter even?  (range110))
  • Usa un solo espacio de sangría paraargumentos de funciones o macros cuando no aparezcan en la mismalínea que el nombre de la función.[link]

    ;; bueno(filter even? (range110))(or uno dos tres);; malo - sangría de dos espacios(filter  even?  (range110))(or  uno  dos  tres)
  • Alinea verticalmenteenlaceslet y palabras clave "keywords", en mapas.[link]

    ;; bueno(let [cosa1"algo"      cosa2"algo más"]  {:cosa1 cosa1:cosa2 cosa2});; malo(let [cosa1"algo"  cosa2"algo más"]  {:cosa1 cosa1:cosa2 cosa2})
  • La linea entre elnombre de una función y su vector de argumentos es opcional y puedeser excluida cuando no conlleve documentación.[link]

    ;; bueno(defnfoo  [x]  (bar x));; bueno(defnfoo [x]  (bar x));; malo(defnfoo  [x] (bar x))
  • Incluye eldispatch-val o valor de envío de un multimétodo en la misma lineaque el nombre de la función.[link]

    ;; bueno(defmethodfoo:bar [x] (baz x))(defmethodfoo:bar  [x]  (baz x));; malo(defmethodfoo:bar  [x]  (baz x))(defmethodfoo:bar [x]  (baz x))
  • Al agregar documentación, enespecial a una función con la forma del ejemplo anterior, asegúrateque la documentación aparezca inmediatamente después del vector deargumentos. De otra forma, éste no será parte de ladocumentación.[link]

    ;; bueno(defnfoo"cadena de documentación"  [x]  (bar x));; malo(defnfoo [x]"cadena de documentación"  (bar x))
  • La línea entre el vector de argumentode una función y su cuerpo es opcional si el cuerpo es pequeño.[link]

    ;; bueno(defnfoo [x]  (bar x));; bueno para una función pequeña(defnfoo [x] (bar x));; bueno para funciones de varias aridades(defnfoo  ([x] (bar x))  ([x y]   (if (predicate? x)     (bar x)     (baz x))));; malo(defnfoo  [x] (if (predicate? x)        (bar x)        (baz x)))
  • Agrega sangría para cadaaridad de una función. De igual forma, alinea verticalmente sus argumentos.[link]

    ;; bueno(defnfoo"Yo tengo dos aridades."  ([x]   (foo x1))  ([x y]   (+ x y)));; malo - sangría innecesaria(defnfoo"I have two arities."  ([x]    (foo x1))  ([x y]    (+ x y)))
  • Ordena las aridades de unafunción de mínimo a máximo número de argumentos. Lo que ocurrefrecuentemente en funciones con distintas aridades es que existe unnúmero K de argumentos los cuales completamente especifican elcomportamiento de la función. Para el caso de aridades N < K, lafunción es parcialmente aplicada y para aridades N > K, la funciónprovee un fold sobre la versión con K aridades sobre varargs, oargumentos variables.[link]

    ;; bueno - fácilmente encontramos la aridad que necesitamos(defnfoo"Yo tengo dos aridades."  ([x]   (foo x1))  ([x y]   (+ x y)));; regular - todas las aridades están basadas en la función con aridad 2(defnfoo"Yo tengo dos aridades."  ([x y]   (+ x y))  ([x]   (foo x1))  ([x y z & mas]   (reduce foo (foo x (foo y z)) mas)));; malo - en desorden(defnfoo  ([x]1)  ([x y z] (foo x (foo y z)))  ([x y] (+ x y))  ([w x y z & mas] (reduce foo (foo w (foo x (foo y z))) mas)))
  • Agrega sangría en cada líneade documentación si ésta abarca más de una sola línea[link]

    ;; bueno(defnfoo"Hola. Esto es una documentación  que abarca varias líneas."  []  (bar));; malo(defnfoo"Hola. Esto es una documentaciónque abarca varias líneas."  []  (bar))
  • Usa las terminaciones de línea de estilo Unix.(Usuarios de BDS, Solaris, Gnu Linux, y OSX ya las usan por defecto.Usuarios de Windows tendrán que ser más cuidadosos.)[link]

    • Si estas usando Git, es posible que quieras agregar el siguientecambio de configuración para ayudar a prevenir que terminacionesde línea de estilo Windows se introduzcan al proyecto:
    bash$ git config --global core.autocrlf true
  • Si existe texto inmediatamente antes o después de una sección entreparéntesis(...), corchetes[...] o llaves{...}, agrega unespacio antes de la apertura y después de la clausura del mismo.[link]

    ;; bueno(foo (bar baz) quux);; malo(foo(bar baz)quux)(foo ( bar baz ) quux)
  • No agregues comas, entreelementos de una secuencia literal.[link]

    ;; bueno[123](123);; malo[1,2,3](1,2,3)
  • Considera mejorar lalegibilidad de mapas literales a través del uso prudente de comas ylíneas.[link]

    ;; bueno{:nombre"Bruce Wayne":identidad-secreta"Batman"};; bueno y discutiblemente más legible{:nombre"Bruce Wayne":identidad-secreta"Batman"};; bueno y discutiblemente más compacto{:nombre"Bruce Wayne",:identidad-secreta"Batman"}
  • Agrega todos los paréntesisque cierran una expresión en una sola línea.[link]

    ;; bueno(when algo  (algo-mas));; malo. Los paréntesis están en distintas líneas(when algo  (algo-mas))
  • Usa líneas vacíasentre formas de nivel superior.[link]

    ;; bueno(defx...)(defnfoo...);; malo(defx...)(defnfoo...)

    Una excepción de esta regla es durante el agrupamiento dedefiniciones relacionadas tipodef.

    ;; bueno(defmin-filas10)(defmax-filas20)(defmin-columnas15)(defmax-columnas30)
  • No agregues líneasvacías en medio de la definición de una función o un macro. Unaexcepción a esta regla es cuando se desea indicar grupos deconstrucciones en pares como aquellas encontradas enlet ycond.[link]

  • Donde sea factible, evita tenerlíneas con más de 80 caracteres.[link]

  • Evita tener espacio en blanco alfinal.[link]

  • Usa un archivo por cada espaciode nombre o namespace.[link]

  • Comienza cada namespacecon una forma comprensiva de tipons. Si es necesario, ésta debeestar compuesta de líneas pararefer,require, eimport, en eseorden.[link]

    (nsejemplos.ns  (:refer-clojure:exclude [next replace remove])  (:require [clojure.string:as s:refer [blank?]]            [clojure.set:as set]            [clojure.java.shell:as sh])  (:import java.util.Date           java.text.SimpleDateFormat           [java.util.concurrent Executors                                 LinkedBlockingQueue]))
  • En la formans, debespreferir el uso de:require :as en lugar de:require :refer enlugar de:require :refer :all. También debes preferir:requiresobre:use, ya que la forma:use es considerada obsoleta.[link]

    ;; bueno(nsejemplos.ns  (:require [clojure.zip:as zip]));; bueno(nsejemplos.ns  (:require [clojure.zip:refer [lefts rights]]));; aceptable según lo garantizado(nsejemplos.ns  (:require [clojure.zip:refer:all]));; malo(nsejemplos.ns  (:use clojure.zip))
  • Evita el uso de namespacesde un solo segmento.[link]

    ;; bueno(nsejemplos.ns);; malo(nsejemplos)
  • Evita el uso denamespaces demasiado largos, es decir, con más de 5 segmentos.[link]

  • Evita funciones con más de 10líneas de código. Idealmente, la mayoría de tus funciones deben detener menos de 5 líneas de código.[link]

  • Evita tener listas deargumentos que requieren más de 3 o 4 argumentos en orden.[link]

  • Evita el uso de referencias directaso adelantadas ya que son muy raramente necesarias.[link]

Sintaxis

  • Evita el uso de funciones comorequire yrefer que alteran tu namespace. Estas funciones soncompletamente innecesarias fuera de un ambiente REPL.[link]

  • Usa la formadeclare para referenciasdirectas o adelantas cuando éstas sean necesarias.[link]

  • Debes preferir funciones de ordensuperior comomap en lugar deloop/recur.[link]

  • Debes preferir pre y postcondiciones sobre pruebas o tests dentro del cuerpo de una función.[link]

    ;; bueno(defnfoo [x]  {:pre [(pos? x)]}  (bar x));; malo(defnfoo [x]  (if (pos? x)    (bar x)    (throw (IllegalArgumentException."x must be a positive number!")))
  • No definas vars dentro de tusfunciones.[link]

    ;; muy malo(defnfoo []  (defx5)...)
  • No ocultes los nombres declojure.core con nuevas definiciones o enlaces locales.[link]

    ;; malo - necesitamos clojure.core/map para referirnos a la funcion(defnfoo [map]...)
  • Usaalter-var-root en lugar dedef paracambiar el valor de una var.[link]

    ;; bueno(defcosa1); valor de cosa es ahora 1; algunos cambios a cosa(alter-var-root #'cosa (constantlynil)); valor de cosa es ahora nil;; malo(defcosa1); algunos cambios a cosa(defcosanil); valor de cosa es ahora nil
  • Usa la formaseq como condición determinación para probar que una secuencia está vacía.[link]

    ;; bueno(defnimprimir-seq [s]  (when (seq s)    (prn (first s))    (recur (rest s))));; malo(defnimprimir-seq [s]  (when-not (empty? s)    (prn (first s))    (recur (rest s))))
  • Usavec en lugar deinto cuando senecesite convertir una secuencia a un vector.[link]

    ;; bueno(vec alguna-seq);; malo(into [] alguna-seq)
  • Usa la formawhen enlugar de(if ... (do ...).[link]

    ;; bueno(when predicado  (foo)  (bar));; malo(if predicado  (do    (foo)    (bar)))
  • Usaif-let en lugar delet +if.[link]

    ;; bueno(if-let [resultado (foo x)]  (algo-con resultado)  (algo-mas));; malo(let [resultado (foo x)]  (if resultado    (algo-con resultado)    (algo-mas)))
  • Usawhen-let en lugar delet +when.[link]

    ;; bueno(when-let [resulatado (foo x)]  (haz-algo-con resulatado)  (haz-algo-mas-con resulatado));; malo(let [resulatado (foo x)]  (when resulatado    (haz-algo-con resulatado)    (haz-algo-mas-con resulatado)))
  • Usaif-not en lugar de(if (not ...) ...).[link]

    ;; bueno(if-not predicado  (foo));; malo(if (not predicado)  (foo))
  • Usawhen-not en lugar de(when (not ...) ...).[link]

    ;; bueno(when-not pred  (foo)  (bar));; malo(when (not pred)  (foo)  (bar))
  • Usawhen-noten lugar de(if-not ... (do ...).[link]

    ;; bueno(when-not predicado  (foo)  (bar));; malo(if-not predicado  (do    (foo)    (bar)))
  • Usanot= en lugar de(not (= ...)).[link]

    ;; bueno(not= foo bar);; malo(not (= foo bar))
  • Usaprintf en lugar de(print (format ...)).[link]

    ;; bueno(printf"Hola, %s!\n" nombre);; ok(println (format"Hola, %s!" nombre))
  • Al hacer comparaciones,recuerda que la funciones en Clojure como<,>, etc. aceptan unnumero variable de argumentos.[link]

    ;; bueno(<5 x10);; malo(and (> x5) (< x10))
  • Debes preferir% en lugar de%1 en funciones literales con solo un argumento.[link]

    ;; bueno#(Math/round %);; malo#(Math/round %1)
  • Debes preferir%1 en lugarde% en funciones literales con más de un argumento.[link]

    ;; bueno#(Math/pow %1 %2);; malo#(Math/pow % %2)
  • No envuelvas funciones enotras funciones anónimas cuando no sea necesario.[link]

    ;; bueno(filter even? (range110));; malo(filter #(even? %) (range110))
  • No uses funcionesliterales si el cuerpo de la función consiste en más de una forma.[link]

    ;; bueno(fn [x]  (println x)  (* x2));; malo ya que necesitas usa la forma `do`#(do (println %)     (* %2))
  • Debes preferir el uso decomplement enlugar de una función anónima.[link]

    ;; bueno(filter (complement predicado?) coll);; malo(filter #(not (predicado? %)) coll)

    Esta regla debe de ser ignorada si el complemento de un predicadoexiste como otra función como es el caso coneven? yodd?

  • Aplica el uso decomp cuando su uso produzcacódigo más simple[link]

    ;; Asumiendo `(:require [clojure.string :as str])`...;; bueno(map #(str/capitalize (str/trim %)) ["tope"" prueba"]);; mejor(map (comp str/capitalize str/trim) ["tope"" prueba"])
  • Aplica el uso departial cuando su usoproduzca código más simple[link]

    ;; bueno(map #(+5 %) (range110));; discutiblemente mejor(map (partial +5) (range110))
  • Debes preferir el uso de threadingmacros como-> o->> en vez de tener muchas expresiones una dentrode la otra.[link]

    ;; bueno(-> [123]    reverse    (conj4)    prn);; no tan bueno(prn (conj (reverse [123])4));; bueno(->> (range110)     (filter even?)     (map (partial *2)));; no tan bueno(map (partial *2)     (filter even? (range110)))
  • Usa:else como la últimaexpresión de prueba encond.[link]

    ;; bueno(cond  (neg? n)"negativo"  (pos? n)"positivo":else"cero");; malo(cond  (neg? n)"negativo"  (pos? n)"positivo"true"cero")
  • Debes preferir el uso decondp en lugar decond cuando el predicado y la expresión no cambian.[link]

    ;; bueno(cond  (= x10):diez  (= x20):veinte  (= x30):treinta:else:desconocido);; much better(condp = x10:diez20:veinte30:treinta:desconocido)
  • Debes preferircase en lugar decond ocondpcuando las expresiones de prueba son contantes durante el tiempo decompilación.[link]

    ;; bueno(cond  (= x10):diez  (= x20):veinte  (= x30):treinta:else:dunno);; mejor(condp = x10:diez20:veinte30:treinta:dunno);; lo mejor(case x10:diez20:veinte30:treinta:dunno)
  • Usa formas cortas encond y formasrelacionadas. Cuando esto no sea posible, trata de proveer pistasvisuales indicando los grupos que son pares a través de comentarios olíneas vacías.[link]

    ;; bueno(cond  (prueba1) (accion1)  (prueba2) (accion2):else   (accion-por-defecto));; más o menos(cond;; prueba caso 1  (prueba1)  (funcion-larga-que-require-una-nueva-linea    (subforma-complicada      (-> 'que-ocupa multiples-lineas)));; prueba caso 2  (prueba2)  (otra-funcion-larga    (con-otra-subforma      (-> 'que-ocupa multiples-lineas))):else  (el-caso-de-accion-por-defecto    (que-tambien-abarca 'multiples                      lineas)))
  • Usa un conjunto oset como predicadocuando sea apropiado[link]

    ;; bueno(remove #{1} [012345]);; malo(remove #(= %1) [012345]);; bueno(count (filter #{\a \e \i \o \u}"un elefante se balanceaba"));; malo(count (filter #(or (= % \a)                    (= % \e)                    (= % \i)                    (= % \o)                    (= % \u))"un elefante se balanceaba"))
  • Usa(inc x) y(dec x) en lugar de(+ x 1) y(- x 1).[link]

  • Usa(pos? x),(neg? x) y(zero? x) enlugar de(> x 0),(< x 0) y(= x 0).[link]

  • Usalist* en lugarde una lista en línea de invocaciones decons.[link]

    ;; bueno(list*123 [45]);; malo(cons1 (cons2 (cons3 [45])))
  • Usa formas de interoperación conJava que han sido endulzadas sintácticamente[link]

    ;;; Creación de objetos;; bueno(java.util.ArrayList.100);; malo(new java.util.ArrayList100);;; Invocación de método estático;; bueno(Math/pow210);; malo(. Math pow210);;; invocación de método de instancia;; bueno(.substring"hola"13);; malo(."hola" substring13);;; acceso a campo o valor estático;; buenoInteger/MAX_VALUE;; malo(. Integer MAX_VALUE);;; acceso de campo o valor de instancia;; bueno(.algunCampo algun-objeto);; malo(. algun-objeto algunCampo)
  • Usa unaanotación compacta para metadatos para quienes sus valores han de serbooleanos.[link]

    ;; bueno(def ^:privatea5);; malo(def ^{:privatetrue}a5)
  • Denota secciones privadas de tu código comotal.[link]

    ;; bueno(defn-funcion-privada []...)(def ^:privatevar-privada...);; malo(defnfuncion-privada []...); no es privada en lo absoluto(defn ^:privatefuncion-privada []...); demasiado verboso(defvar-privada...); no es privada en lo absoluto
  • Para acceder una var privada, porejemplo, durante tus pruebas, usa la forma@# algun.ns/var[link]

  • Ten cuidado con respecto aexactamente que se le adjuntan metadatos.[link]

    ;; se le adjuntan metadatos a la var referenciada por `a`(def ^:privatea {})(meta a);=> nil(meta #'a);=> {:private true};; se le adjuntan metadatos al valor vacío del hash-map(defa ^:private {})(meta a);=> {:private true}(meta #'a);=> nil

Nombramiento

Las únicas dificultades reales en la programación son la invalidaciónde caché y el nombrar las cosas.
-- Phil Karlton

  • Al nombrar tus namespaces, usa lassiguientes dos esquemas:[link]organizacion

    • proyecto.modulo
    • organizacion.proyecto.modulo
  • Usa el nombramiento estilolisp consegmentos compuestos de namespaces como por ejemplodiego.project-euler)[link]

  • Usa el nombramiento estilolisp paranombres de funciones y variables.[link]

    ;; bueno(defalguna-var...)(defnalguna-funcion...);; malo(defalgunaVar...)(defnalgunafuncion...)(defalguna_funcion...)
  • Usael nombramiento estiloCamelCase para protocolos, records, y tipos yasegúrate de mantener en mayúscula siglas como HTTP, RFC, XML.[link]

  • Al nombrar métodos quefuncionan como predicados, es decir, aquellos que retornan un valorbooleano de true o false, deben de terminar con un signo deinterrogación.[link]

    ;; bueno(defnpalindromo?...);; malo(defnpalindromo-p...); Estilo de Common Lisp(defnes-palindromo...); Estilo de Java
  • Los nombres defunciones o macros que no son seguras bajo transacciones STM deben determinar con un signo de admiración.[link]

  • Usa-> al nombrar funciones deconversion.[link]

    ;; bueno(defnf->c...);; no tan bueno(defnf-a-c...)
  • Agrégaleasteriscos al principio y al final de los nombres devariables dinámicas.[link]

    ;; bueno(def ^:dynamic *a*10);; malo(def ^:dynamica10)
  • Recuerda que no es necesario usarninguna anotación especial para denotar constantes. Esto es debido aque se asume que todo es constante a menos que se especifique locontrario.[link]

  • Usa un guión bajo_para denotar argumentos o variables de deconstrucción cuyo valor no esusado por el resto del cuerpo.[link]

    ;; bueno(let [[a b _ c] [1234]]  (println a b c))(dotimes [_3]  (println"Hello!"));; malo(let [[a b c d] [1234]]  (println a b d))(dotimes [i3]  (println"Hola!"))
  • Sigue el ejemplo del namespaceclojure.core usando nombres comopred ycoll.

    • en funciones, usa
      • f,g,h - para representar argumentos
      • n - para representar una cantidad
      • index,i - para representar un índice numeral
      • x,y - para números
      • xs - para secuencias
      • m - para mapas
      • s - para strings
      • re - para expresiones regulares o regex
      • coll - para colecciones
      • pred - para predicados
      • & more - para representar argumentos variados
      • xf - para una xforma o un transducer
    • en macros, usa
      • expr - para expresiones
      • body - para el cuerpo del macro
      • binding - para el vector de enlace en el macro

Colecciones

Es mejor tener 100 funciones que operan una sola estructura de datosque tener 10 funciones que operan en 10 estructuras de datos
--Alan J. Perlis

  • A menos de que su estructura sea necesaria,evita usar listas para uso genérico.[link]

  • Debes preferir el uso dekeywords como claves o keys.[link]

    ;; bueno{:nombre"Daniel":edad30};; malo{"nombre""Daniel""edad"30}
  • Debes preferir el uso del sintaxisliteral para colecciones en vez de sus respectivos constructores. Sinembargo, al definir conjuntos o sets, solo usa el sintaxis literal silos valores son constantes al momento de compilación.[link]

    ;; bueno[123]#{123}(hash-set (func1) (func2)); Valores determinados en compilación;; malo(vector123)(hash-set123)#{(func1) (func2)}; Lanzará una excepción si (func1) = (func2)
  • En lo posible, evita tener que acceder miembros de una colecciónusando su índice.[link]

  • Debes preferir el usode keywords como funciones al acceder valores de mapas.[link]

    (defm {:nombre"Daniel":edad30});; bueno(:nombre m);; más verboso de lo necesario(get m:nombre);; malo - suceptible a un NullPointerException(m:nombre)
  • Utiliza el hecho de que la mayoría decolecciones actúan como funciones de sus miembros.[link]

    ;; bueno(filter #{\a \e \o \i \u}"esto es una prueba");; malo - demasiado feo para ser compartido
  • Utiliza el hecho de que keywords puedenactuar como funciones de una colección[link]

    ((juxt:a:b) {:a"ala":b"bala"})
  • Evita hacer tus colecciones"transient", a menos que se trate de pociones de tu código que necesitanmuy alto rendimiento.[link]

  • Evita el uso de colecciones de Java.[link]

  • Evita el uso de arrays de Java,excepto en escenarios de interoperabilidad o código de altorendimiento que trata con tipos de Java primitivos.[link]

Mutación

Refs

Considera envolver todas tus usos de input/output, o I/O con el macroio! para evitar malas sorpresas si accidentalmente llamas ese tipo decódigo en una transacción. Esto es debido a que las transaccionespueden ser llamadas varias veces y, por ende, el código que contienendebe ser puro (sin efectos externos).[link]

  • Evita el uso deref-set en loposible.[link]

    (defr (ref0));; bueno(dosync (alter r +5));; malo(dosync (ref-set r5))
  • Intenta de mantener al mínimo el tamaño de tus transacciones, esdecir, la cantidad de trabajo encapsulada en ellas.[link]

  • Evitatener transacciones largas y cortas interactuando con un mismo Ref.[link]

Agents

  • Usasend solamente para accioneslimitadas por la CPU y que no bloquean hilos o threads, en especialel de I/O.[link]

  • Usasend'off para acciones quepueden, de alguna forma, bloquear un thread.[link]

Átomos

  • Evita actualizarátomos dentro de transacciones STM.[link]

  • En lo posible, debespreferir el uso deswap! en lugar dereset!.[link]

    (defa (atom0));; bueno(swap! a +5);; no tan bueno(reset! a5)

Strings o cuerdas

  • Debes preferir el uso de funciones de manipulaciones provenientes declojure.string en lugar de interoperar con Java o escribir tuspropias versiones.[link]

    ;; bueno(clojure.string/upper-case"daniel");; malo(.toUpperCase"daniel")

Excepciones

  • Si es necesario lanzaruna excepción, asegúrate de usar tipos de excepciones ya existentes.Por ejemplo,java.lang.IllegalArgumentException,java.lang.UnsupportedOperationException,java.lang.IllegalStateException,java.io.IOException[link]

  • Debes preferir el usodewith-open en lugar definally.[link]

Macros

  • No escribas un macro si una función es suficiente.[link]

  • Construyeun ejemplo de uso para un macro antes de escribir el macro en sí.[link]

  • En lo posible, divide macroscomplicados en funciones pequeñas.[link]

  • Un macro debe proveerazúcar sintáctico, es decir, debe simplificar el formaciónsintáctica de la expresión. El núcleo del macro deben de serfunciones simples ya que esto incrementa su capacidad de compilación.[link]

  • Debes preferir formas con sintaxis citado en lugar de laconstrucción manual de listas.[link]

Comentarios

Buen código es su mejor propia documentación. Al prepararte paraagregar un comentario, debes preguntarte, "¿Cómo puedo mejorar micódigo de tal forma que este comentario no sea necesario?" Mejora tucódigo primero y después documéntalo para hacerlo aun más claro.
-- Steve McConnell

  • Haz que tu código sea tanauto-documentado como sea posible.[link]

  • Escribecomentarios de encabezadura con al menos 4 puntos y comas.[link]

  • Escribe comentarios principales con 3 puntos y comas.[link]

  • Escribe comentarios acerca de un fragmento de código con dos puntos ycomas. Además, asegúrate de escribir el comentario antes del fragmentoque al que hace referencia y alinéalo a él.[link]

  • Escribe comentarios marginales con un punto y coma.[link]

  • Asegúrate de siempre tener al menos un espacio entre un punto y coma yel texto que lo prosigue.[link]

    ;;;; Título;;; Esta sección de código tiene estas importantes implicaciones:;;;   1. Foo.;;;   2. Bar.;;;   3. Baz.(defnfuncion [argumento];; Si zob, entonces veeblefitz.  (quux zot        mumble; Zibblefrotz.        frotz))
  • Comentarios compuestos de más de una palabra deben empezar conmayúscula y usar puntuación. También separa oraciones con unun espacio.[link]

  • Evita el uso de comentarios innecesarios.[link]

    ;; malo(inc contador); Incrementa el valor del contador por uno
  • Mantén vigentes tus comentarios. Uncomentario desactualizado es peor que no tener un comentario.[link]

  • Debes preferir el uso demacro lector#_ en lugar de un comentario regular al comentar unaforma en su totalidad.[link]

    ;; bueno(+ foo #_(bar x) delta);; malo(+ foo;; (bar x)   delta)

Buen código es como un buen chiste... no necesita explicación.
-- Russ Olsen

  • Evita escribir comentarios paradocumentar código malo. Mejora tu código con el fin de hacer que seauto documente. ("Hacer, o no hacer. No hay intentar." --Yoda)[link]

Anotaciones de comentarios

  • Anotaciones debe de ser escritas en lalínea inmediatamente antes del código al que referencia.[link]

  • La anotación debe estar compuestapor el keyword de anotacion seguido por dos puntos y un espacio,después por una nota describiendo el problema.[link]

  • Si la descripción de un problemarequiere el uso de múltiples líneas, todas las líneas deben seguirla misma indentación o sangría de la primera línea.[link]

  • Marca tu anotación confecha e iniciales para que su relevancia sea fácilmente verificada.[link]

    (defnalguna-funcion  [];; FIXME: Esto ha causado problemas ocasionalmente en v1.2.3.;;        Es posible que sea relacionado con la actualizacion;;        de BarUtilidad (xz 13-1-31)  (baz))
  • En casos donde el problema estan evidente que cualquier tipo de documentación es redundante,anotaciones sin notas pueden ser hechas después del código al que sehace referencia. Recuerda que este uso debe ser la excepción y no laregla.[link]

    (defnbar  []  (sleep100)); OPTIMIZE
  • UsaTODO para marcar funcionalidad que debeser agregada después.[link]

  • UsaFIXME para marcar código fallido que debeser arreglado.[link]

  • UsaOPTIMIZE para marcar código lento oineficiente que puede causar problemas de rendimiento[link]

  • UsaHACK para anotar usos cuestionables de laspracticas usadas que deben ser corregidas.[link]

  • UsaREVIEW para marcar código que debe serrevisado para confirmar que esta trabajando correctamente. Porejemplo:REVIEW: ¿Estamos segurlos que el cliente untiliza X en este momento?[link]

  • Usa otros keywords de anotacioncuando sea apropriado y asegúrate de documentarlos en elREADME oarchivo equivalente de tu proyecto.[link]

Existencial

  • Escribe código de forma funcionalusando mutación solo cuando tenga sentido.[link]

  • Sé consistente con el uso de esta guía.[link]

  • Usa el sentido común.[link]

Herramientas

Aquí presentamos algunas herramientas creadas por la comunidad deClojure que pueden ayudarte en tu camino para escribir Clojure idiomático.

  • Slamhound es unaherramienta que automáticamente genera declaraciones dens para tucódigo existente.

  • kibit es un analizador estático decódigo para Clojure que usa[core.logic](https://github.com/clojure/core.logic para encontrarpatrones de código para los cuales pueden existir formas, funciones, omacros más idiomáticos.

Pruebas

  • Guarda tus pruebas en undirectorio separado. Normalmente, bajotest/tuproyecto/ en lugardesrc/tuproyecto/. Tu herramienta de construcción esresponsable de hacer que estos archivos estén disponibles donde seannecesarios. La mayoría de modelos hacen esto automáticamente.[link]

  • Nombre tu nstuproyecto.algo-test, un archivo que usualmente es nombradotest/tuproyecto/algo_test.clj (o.cljc,cljs).[link]

  • Al usarclojure.test, define tus prubeas condeftesty nombralesalgo-test`. Por ejemplo

    ;; bueno(deftestalgo-test...);; malo(deftestalgo-tests...)(deftesttest-algo...)(deftestalgo...)

    [link]

Organización de librerías

  • Si estas publicando librerías con elfin de que sean usadas por otros, asegúrate de seguir laCentralRepositoryguidelinespara escoger tugroupId andartifactId. Esto ayuda prevenirconflictos de nombre y facilita cualquier tipo de uso. Un buenejemplo es el deComponent.[link]

  • Evita incluir dependencias innecesarias. Por ejemplo, es preferiblecopiarle una función de 3 líneas a tu proyecto en lugar de unadependencia que conlleva cientos de vars que no piensas usar.[link]

  • Separa la funcionalidadcentral de tu librería y sus puntos de integración en distintosartefactos. De esta forma, usuarios pueden consumir tu librería sintener que estar atados a preferencias de herramientas externas. Porejemplo,Componentprovee functionalidad central, yreloaded proveeintegración con Leiningen.[link]

Contribuciones

Nada escrito en esta guía está escrito en piedra. Mi deseo es trabajarjunto con todos aquellos interesados en el estilo de código Clojurecon el fin de poder construir un recurso que sea beneficioso para lacomunidad entera de Clojure.

No tengas miedo de abrir tickets o hacer pull requests con mejorías.De antemano, muchas gracias por tu ayuda!

Es posible contribuir a la guía de estilo financialmente a través degittip.

Contribuye a través de Gittip

Licencia

Creative Commons LicenseEste trabajo está licenciado bajo la licenciaCreative Commons Attribution 3.0 Unported License

Difunde la palabra

Una guía de estilo escrita por la comunidad es de poco uso si la mismacomunidad no sabe de su existencia. Por ende, comparte la guía con tusamigos y colegas. Cada comentario, sugerencia u opinión hace que estaguía sea solo un tanto mejor. Y queremos tener la mejor guía posible, cierto?

Salud,Bozhidar

About

Una guía de estilo para Clojure escrita por la comunidad

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp