2010-06-17 11 views
11

Me interesa cómo las personas estructuran su código fuente de Clojure.Aproximación idiomática para estructurar el código fuente de Clojure

están utilizando para Java, estoy bastante familiarizado con el paradigma de una clase por archivo de código fuente, la agrupación de todas las definiciones de datos y el método con comentarios y anotaciones etc.

apropiadas Sin embargo Clojure ofrece mucha más flexibilidad y no estoy seguro de cómo debo estructurar mi proyecto (propensos a terminar como una aplicación de tamaño medio, tal vez 5.000 líneas con tres o cuatro subsistemas distintos)

En particular estoy luchando con:

  • ¿Qué pautas debo usar para determinar si el código debe estar en un solo espacio de nombres frente a separado en espacios de nombres diferentes?
  • ¿Debería cada protocolo/tipo de datos tener su propio espacio de nombres + archivo fuente con un conjunto de funciones asociado?
  • ¿Cuándo debo solicitar vs. usar otros espacios de nombres?

Respuesta

8

Soy de origen Java también, junto con un poco de Ruby y un poco de Go. Esto es lo que estoy haciendo en este momento, alrededor de un mes en Clojure:

  • Estoy pensando en un espacio de nombres como una unidad semántica, que es el código que va de la mano para un propósito particular, como un tipo de datos y las operaciones en eso.

que tienen dos convenciones para espacios de nombres vs archivos:

  • Para las unidades más bien pequeñas que caben cómodamente en un solo archivo (estoy usando ~ 1000 líneas que el límite en el que un archivo debe ser dividido) Tengo un espacio de nombres por archivo, con la ruta del directorio más el nombre del archivo igual que el espacio de nombres. Esto es algo bueno en Java, creo, hace que encontrar el espacio de nombres del archivo o viceversa sea muy sencillo.
  • Para unidades más grandes que necesitan varios archivos, estoy usando la convención Go: el espacio de nombres coincide con la ruta del directorio, y todos los archivos en el directorio comparten el mismo espacio de nombres. En estos casos, normalmente asigno un archivo primario con un nombre fijo ('main') que carga e interactúa con los demás.

Como un ejemplo de espacio de nombres, tengo un analizador que lee un formato y lo convierte a HTML. Tengo un único espacio de nombres para el analizador (la unidad semántica) y varios archivos en el directorio divididos en subfuncionalidad: Lexer, analizador, conversión HTML y un archivo principal que contiene la API pública principal para usar el analizador.

No utilizaría automáticamente un espacio de nombres por tipo de datos, depende del alcance del tipo de datos. Si es uno grande, tal vez. Pero para un tipo de datos como Point, con dos campos y un par de funciones, prefiero incluirlo en un espacio de nombres más general como Geometry.

Requerir vs. uso:

  • Requerir con una adecuada alias corto en casi todas partes.
  • Esto también permite la reutilización de nombres de núcleos: mi tipo de árbol de propósito especial tiene la operación "get" para encajar con mapas; using require no hay conflicto: "get" es el núcleo de Clojure get, "tree/get" es el de mi tipo de datos.
  • Uso el "uso" solo para lo que considero "extensiones principales", como cuando hago mi propio "mapa-si", que es un mapa y un filtro, todo en uno.
+0

gracias - eso parece tener mucho sentido, ¡genial para obtener sus perspectivas! – mikera

Cuestiones relacionadas