Reescribir Java a clojure
vaadin (3)
Mi compañía me acaba de pedir que reescriba una aplicación Java grande (50,000 líneas simples de código) (una aplicación web que usa JSP y servlets) en Clojure. ¿Alguien más ha recibido consejos sobre lo que debo vigilar?
Tenga en cuenta que conozco Java y Clojure bastante bien.
Actualizar
Hice la reescritura y entró en producción. Es bastante extraño ya que la reescritura terminó yendo tan rápido que se hizo en aproximadamente 6 semanas. Debido a que no se necesitaba mucha funcionalidad, terminó siendo más como 3000 líneas de Clojure. Escuché que están contentos con el sistema y está haciendo exactamente lo que querían. El único inconveniente es que el tipo que mantiene el sistema tuvo que aprender Clojure desde cero, y fue arrastrado a patear y gritar. Recibí una llamada de él el otro día diciendo que amaba a Lisp ahora ... divertido :)
Además, debería darle una buena mención a Vaadin. El uso de Vaadin probablemente representó la mayor parte del tiempo ahorrado y la brevedad del código como lo hizo Clojure. Vaadin sigue siendo el mejor framework web que he usado en mi vida, ¡aunque ahora estoy aprendiendo ClojureScript con ira! (Tenga en cuenta que tanto Vaadin como ClojureScript usan los marcos de GUI de Google debajo del capó)
¿Qué aspectos de Java incluye tu proyecto actual? Logging, transacciones de base de datos, transacciones declarativas / EJB, capa web (mencionó JSP, servlets) etc. He notado que el ecosistema Clojure tiene varios microarmas y bibliotecas con el objetivo de hacer una tarea y hacerlo bien. Sugeriría evaluar bibliotecas según su necesidad (y si se escalaría en proyectos grandes) y tomar una decisión informada. (Descargo de responsabilidad: soy el autor de http://code.google.com/p/bitumenframework/ ) Otra cosa a tener en cuenta es el proceso de compilación: si necesita una configuración compleja (desarrollo, prueba, puesta en escena, prod) puede tener para dividir el proyecto en módulos y tener el proceso de compilación con guiones para facilitar.
El mayor "problema de traducción" probablemente irá de una metodología Java / OOP a un paradigma de programación Clojure / funcional.
En particular, en lugar de tener un estado mutable dentro de los objetos, el "modo Clojure" es separar claramente el estado mutable y desarrollar funciones puras (sin efectos secundarios). Probablemente ya sepas todo esto :-)
De todos modos, esta filosofía tiende a llevarnos a un estilo de desarrollo de "abajo hacia arriba" en el que enfoca los esfuerzos iniciales para construir el conjunto adecuado de herramientas para resolver su problema y, finalmente, las conecta al final. Esto podría parecerse a esto
Identifique las estructuras de datos clave y transfórmelas en mapas Clojure inmutables o definiciones de registros. No tengas miedo de anidar muchos mapas inmutables: son muy eficientes gracias a las persistentes estructuras de datos de Clojure. Vale la pena ver este video para obtener más información.
Desarrolle pequeñas bibliotecas de funciones puras orientadas a lógica de negocios que operan en estas estructuras inmutables (por ejemplo, "agregar un artículo al carrito de compras"). No es necesario que haga todos estos elementos a la vez, ya que es fácil agregarlos más adelante, pero es útil hacer algunos para facilitar las pruebas y demostrar que sus estructuras de datos funcionan ... de cualquier manera, en este caso. señalar que en realidad puede comenzar a escribir cosas útiles de manera interactiva en el REPL
Desarrolle por separado rutinas de acceso a datos que puedan mantener estas estructuras hacia / desde la base de datos o la red o el código heredado de Java, según sea necesario. La razón para mantener esto separado es que no quiere que la lógica de persistencia esté ligada a sus funciones de "lógica de negocios". Es posible que desee ver ClojureQL para esto, aunque también es bastante fácil ajustar el código de persistencia de Java que desee.
Escribir pruebas unitarias (p. Ej. Con clojure.test ) que cubran todo lo anterior. Esto es especialmente importante en un lenguaje dinámico como Clojure ya que a) usted no tiene una red de seguridad de la verificación de tipo estático yb) le ayuda a estar seguro de que sus construcciones de nivel inferior funcionan bien antes de construir demasiado. arriba de ellos
Decide cómo quieres usar los tipos de referencia de Clojure (vars, refs, agents y atoms) para gestionar cada estado de nivel de aplicación mutable de parte. Todos funcionan de forma similar, pero tienen una semántica transaccional / de concurrencia diferente según lo que se intenta hacer. Los Refs probablemente sean su opción predeterminada: le permiten implementar el comportamiento transaccional de STM "normal" envolviendo cualquier código en un bloque (dosync ...).
Seleccione el marco web general correcto, Clojure ya cuenta con algunos, pero recomiendo encarecidamente Ring: vea este excelente video " Un anillo para unirlos " más Fleet o Enlive o Hiccup según su filosofía de Enlive plantillas. Luego use esto para escribir su capa de presentación (con funciones como "traducir este carrito de compras a un fragmento HTML apropiado")
Finalmente, escribe tu aplicación usando las herramientas anteriores. Si ha realizado correctamente los pasos anteriores, esta será la parte más fácil, ya que podrá compilar toda la aplicación mediante la composición adecuada de los diversos componentes con muy poco texto estándar.
Esta es más o menos la secuencia en la que atacaría el problema, ya que representa ampliamente el orden de las dependencias en su código y, por lo tanto, es adecuado para un esfuerzo de desarrollo de "abajo hacia arriba". Aunque, por supuesto, con un buen estilo ágil / iterativo, probablemente te encuentres avanzando temprano hacia un producto final demostrable y luego vuelvas a los pasos anteriores con bastante frecuencia para extender la funcionalidad o refactorizar según sea necesario.
ps Si sigue el enfoque anterior, me fascinaría saber cuántas líneas de Clojure se necesitan para que coincida con la funcionalidad de 50,000 líneas de Java
Actualización : dado que esta publicación se escribió originalmente, surgieron un par de herramientas / bibliotecas adicionales que se encuentran en la categoría "debe verificarse":
Encontré que la parte más difícil era pensar en la base de datos. Haz algunas pruebas para encontrar las herramientas adecuadas que quieras usar allí.