Si Java es un lenguaje de propósito general, y construir un programa es algo que se puede describir usando el lenguaje Java, ¿por qué no es esta la mejor manera de escribir archivos de compilación y en su lugar utilizamos herramientas como Ant, Maven y Gradle? ¿No sería más sencillo y también eliminaría la necesidad de aprender otro lenguaje de programación más? (Por cierto, esta pregunta también se puede aplicar a otros idiomas, como C #)
java
c#
builds
build-system
vainolo
fuente
fuente
Respuestas:
Herramienta específica para un propósito específico
Verbosidad
Los lenguajes de uso general son a menudo demasiado detallados. Si tuviera que administrar una compilación en Java, me deprimiría muy rápidamente por el tamaño de la bestia. Sin embargo, podría ser fácilmente manejable usando un DSL escrito en Java. Y hasta cierto punto así es como puedes ver Gradle (para Groovy) y Buildr (para Ruby).
Dificultad
Los lenguajes de uso general son difíciles. Bueno, no creo que la programación sea difícil y nadie pueda aprenderla, pero el punto es: ¡tu ingeniero de construcción no es necesariamente tu programador!
Propósito
Eso es más o menos en la intersección de dificultad y verbosidad . Un lenguaje está diseñado para un propósito, y aquí estamos hablando de algo muy específico. Entonces, ¿por qué necesitarías o querrías usar un lenguaje de propósito general ? Para las compilaciones, necesitas:
Realmente no necesitas mucho más.
Claro que es molesto cuando su sistema de compilación parece que no es lo suficientemente flexible para ese caso de uso especial que está buscando, pero probablemente sea mucho mejor que la alternativa para la mayoría de las personas.
Esa es probablemente la razón por la cual hay una polaridad entre las personas que prefieren los sistemas de compilación declarativa en lugar de la mayoría de las ocasiones programables: supongo que un desarrollador podría tener una tendencia natural a buscar formas de salir de la caja.
Espera, ¿realmente necesitamos una herramienta?
Otra pregunta relacionada sería: ¿realmente necesitamos una herramienta de compilación? ¿No es el hecho de que existan en todos los idiomas la señal de que llenan un vacío que ni siquiera debería estar allí en primer lugar?
Algunos idiomas no requieren necesariamente una herramienta de compilación. Por ejemplo, la mayoría de los lenguajes de script no necesitan uno y se resuelven en el momento de la carga. O tome Go, cuyo compilador se encargará de todo por usted, lo cual es un buen contrapunto: ¿qué pasaría si un compilador como gcc de repente no necesitara un montón de banderas, un enlazador y un archivo MAKE para morir todo junto? ¿O si javac no necesitaba un build.xml o pom.xml para decirle qué hacer? ¿No debería la gestión de dependencias directamente ser parte de las herramientas propias del lenguaje, ya que las dependencias son parte del programa final?
Seguramente parece un enfoque mucho más simple para el usuario (el constructor). Aunque se podría argumentar que lo están haciendo de manera oculta y le están quitando su elección y oportunidades para influir en ese proceso de compilación (pero entonces esperaría que tal herramienta permita extensiones del compilador y cosas similares). Además, solíamos ver las herramientas y el lenguaje como dos cosas separadas, por lo que podría parecer inseguro de repente tenerlas tan estrechamente unidas.
No creo que el lenguaje que usa para construir sus programas sea el problema. Lo que debería importar es el lenguaje que usa para programar y su plataforma central y herramientas, y todavía estamos avanzando en eso.
Personalmente, utilicé make / gmake / autotools / pmk y estuve contento con ellos para C, y comencé con Java cuando todo lo que teníamos era make, luego hormiga, y ahora generalmente prefiero a Maven a todas estas alternativas. Aunque puedo ver el valor en gradle, buildr y otros, pero hasta ahora me gusta la prevalencia de maven, hasta que se produce un cambio más significativo. Además, me gusta que sea rígido, pero aún así te deja la capacidad de evitarlo si es necesario. Que no es fácil es algo bueno.
Es una herramienta de construcción. Solo aprende a abrazarlo y no luchar contra él. Es una batalla perdida. O al menos uno muy muy largo.
fuente
Java
es un imperativo lengua,Ant
,Maven
, etc, son declarativas idiomas:Los lenguajes de compilación le dicen al constructor qué se debe hacer, desde dónde se debe tomar, etc. El motor que ejecuta la compilación (que está escrito en un lenguaje imperativo, como ha notado @ElliottFrisch), lee estas instrucciones y las cumple.
Los lenguajes declarativos pueden parecer más apropiados en escenarios de compilación, ya que las tareas de compilación generalmente son las mismas en todas partes, y se considera más fácil de mantener y legible en esa forma que en forma de código completo.
fuente
Si observa las características de un sistema de compilación típico, encontrará:
Si se propone escribir una serie de archivos de compilación utilizando algún lenguaje (Java / C # / Python / etc.), aproximadamente en la tercera o cuarta iteración se conformaría con (a) mantener la mayoría de los datos y comandos externos como datos en algo como XML (b) escribiendo el "motor de compilación" en su idioma favorito.
También le resultará útil tratar algunos de los datos en su XML como un lenguaje interpretado, para activar varias características en el motor de compilación. También puede interpretar algunas macros o realizar sustituciones de cadenas en los datos.
En otras palabras, terminarías con Make, o Ant, o Rake, o MsBuild. Un lenguaje imperativo para las cosas que hace bien, y estructuras de datos para describir lo que quiere hacer, ahora generalmente en XML.
fuente
Varios factores cuentan contra el uso de Java / C ++ / C # en estos casos.
En primer lugar, tendría que compilar su script de compilación antes de poder ejecutarlo para compilar su aplicación. ¿Cómo especificaría los paquetes, las banderas, las versiones del compilador, las rutas de herramientas necesarias para construir su script de compilación? Ciertamente, podría encontrar una forma de evitarlo, pero es mucho más sencillo tener un lenguaje que no necesite ese paso de compilación (por ejemplo, python) o un lenguaje que su herramienta de compilación comprenda de forma nativa.
En segundo lugar, los archivos de compilación tienen muchos datos, mientras que Java / C ++ / C # están mucho más orientados a escribir código y algoritmos. Java y sus amigos no tienen una representación muy sucinta de todos los datos que desea almacenar.
En tercer lugar, Java y sus amigos necesitan mucha repetitiva para ser válidos. El archivo de compilación tendría que estar dentro de un método dentro de una clase con todas sus importaciones. Al usar un lenguaje de secuencias de comandos o un lenguaje personalizado, puede evitar toda esa estructura repetitiva y solo tener los detalles de compilación.
fuente
¡En efecto! ¿Por qué no usar un lenguaje poderoso y expresivo para un problema que es más complejo de lo que la gente piensa (inicialmente)? Especialmente cuando las personas que enfrentan el problema ya son competentes con dicho lenguaje. (La construcción es un problema de los programadores y la mejor manera de resolverla los programadores).
También me hice esta pregunta hace años y decidí que Java es un buen lenguaje para definir compilaciones, especialmente para proyectos Java. Y, como resultado, comencé a hacer algo al respecto.
DESCARGO DE RESPONSABILIDAD : En esta respuesta, estoy promoviendo iwant , un sistema de compilación que estoy desarrollando. Pero dado que esta es una discusión obstinada de todos modos, estoy seguro de que está bien.
No voy a dar más detalles sobre los beneficios de Java (potencia y expresividad) ni quiero específicamente. Si está interesado, puede leer más en la página de iwant .
En cambio, consideraré por qué Java (y otras GPL) se descartan tan fácilmente como inadecuados para la construcción. Muchas respuestas y comentarios aquí son buenos ejemplos de tal pensamiento. Consideremos algunos de los argumentos típicos:
"Java es imprescindible, pero las compilaciones se definen mejor de manera declarativa" , podrían decir.
Cierto. Pero cuando se usa un lenguaje como metalenguaje para un DSL interno , lo que realmente cuenta es su sintaxis . Incluso un lenguaje imperativo como Java puede ser engañado para ser declarativo. Si se ve y se siente declarativo, es (para fines prácticos) declarativo. Por ejemplo:
Este es un ejemplo real del proyecto de demostración de iwant .
De hecho, compare esto con algunos sistemas de compilación supuestamente declarativos que exponen a sus usuarios a verbos imperativos como "prueba" o "compilación". La declaración anterior contiene solo sustantivos, no verbos. Compilar y probar son tareas que iwant maneja implícitamente para otorgar al usuario los sustantivos que desea. No es el idioma Así es como lo usas.
"Java es detallado"
Sí, una gran cantidad de código Java es detallado. Pero de nuevo, no es el lenguaje, es cómo lo usas. Si una implementación es detallada, simplemente encapsúlela detrás de una buena abstracción. Muchas GPL proporcionan mecanismos adecuados para esto.
Solo imagine el fragmento de Java anterior escrito en XML. Reemplace los paréntesis con corchetes angulares y muévalos. ¡Y luego duplique cada palabra clave como etiqueta de cierre! Java como sintaxis no es detallada.
(Lo sé, comparar con XML es como quitarle un caramelo a un bebé, pero muchas construcciones están definidas en XML).
"Tendrías que compilar tu script de compilación"
Este es un punto válido. Sin embargo, es solo un problema técnico menor a resolver. Podría haberlo resuelto usando beanshell o algún otro intérprete. En cambio, lo resolví tratándolo como un problema más de compilación y bootstrapping con un simple shell o script de hormiga que compila y ejecuta un simple bootstrapper de Java.
"Java tiene repetitivo"
Cierto. Debe importar clases, debe mencionar "public", "class", etc. Y aquí, las DSL externas simples obtienen una victoria inicial fácil.
Y si su proyecto es tan trivial que este estándar es significativo, felicidades. Su problema no es difícil y realmente no importa cómo lo resuelva.
Pero muchos proyectos necesitan mucho más que compilación, informe de cobertura y empaque. Si el estándar de Java es aceptable para los problemas de los clientes, ¿por qué no crear problemas? ¿Por qué hacer zapatos solo para los hijos de otros?
fuente
Una cosa que no creo que las otras respuestas hayan abordado es que las limitaciones y la transparencia de estos lenguajes de compilación son una gran parte de lo que los hace útiles. Tomemos a Maven, por ejemplo. Sí, ejecuta compilaciones pero también define dependencias. Esto permite que una compilación de Maven elimine esas dependencias y observe sus dependencias y así sucesivamente.
Considere si esto se hizo con Java directamente. La herramienta de compilación vería que hay una dependencia. Luego necesitaría desplegar otra aplicación Java y ejecutarla para determinar cuáles son sus dependencias. Pero para Maven, simplemente mira las declaraciones de dependencia. El archivo de compilación de Maven es transparente. Un lenguaje completo de Turing es inherentemente no transparente y, por lo tanto, es inferior para algunos fines como este.
fuente