Recientemente he estado usando algunas herramientas de compilación para un proyecto Nodejs en el trabajo cuando me di cuenta de que la herramienta / sistema de compilación principal de la mayoría de los lenguajes usa un lenguaje diferente al lenguaje de programación subyacente.
Por ejemplo, make no usa C o C ++ para escribir scripts y ant (ni Maven) no usa Java como su lenguaje para los scripts.
Los lenguajes más nuevos como Ruby usan el mismo lenguaje para crear herramientas como rake , lo que tiene sentido para mí. Pero, ¿por qué no siempre ha sido así? ¿Cuál es la ventaja de tener una herramienta de compilación que utiliza un idioma diferente del idioma subyacente?
programming-languages
history
build-system
joshin4colours
fuente
fuente
make
nuevamente (que de todos modos se implementa en C)?Respuestas:
La elección de qué lenguaje de programación usar para hacer algo debe depender de las características específicas de ese objetivo y no de las otras tareas relacionadas con ese proyecto.
Una herramienta de compilación realiza un trabajo muy específico, y no importa qué idioma esté utilizando para el proyecto principal, una herramienta de compilación es un software en sí misma.
Intentar vincular el proyecto principal y su herramienta de construcción podría ser una muy mala decisión. Lo que debe necesitar con una herramienta de compilación es principalmente un proceso rápido de reglas simples, con una administración rápida de archivos e IO.
Si lenguajes como el rubí se utilizan para implementar su herramienta de construcción, se relaciona más con las características de ese lenguaje que con la supuesta necesidad de mantener todo escrito con el mismo idioma.
fuente
No es imposible escribir una herramienta de compilación que use un lenguaje como C o Java como sus lenguajes de script. Sin embargo, las herramientas de construcción se benefician del uso de más lenguajes de script declarativos . Imagina el dolor y la repetición de escribir un archivo MAKE (o build.xml, o lo que sea) en C.
Las herramientas de construcción se benefician del uso de DSL, una tarea para la cual C no es una opción particularmente buena. C es demasiado general para una herramienta de compilación y demasiado preocupado por los detalles propensos a errores y de bajo nivel. Por ejemplo, no desea preocuparse por la gestión explícita de la memoria en una herramienta de compilación. Entonces, incluso si usa una sintaxis tipo C, probablemente usaría la recolección de basura en su herramienta de scripting, en ese momento ¿por qué no simplemente usar un DSL dedicado?
Tiene sentido que se pueda usar Ruby para esto, ya que es un lenguaje de nivel superior y más declarativo que C o Java. Ver también: Gradle, sbt.
fuente
Imagine the pain and boilerplate of writing a makefile (or build.xml, or whatever) in C.
Imagine el dolor y el desorden de tratar de expresar una lógica condicional no trivial (ya sabe, material imperativo estándar) en un script XML declarativo. Oh, espera, no tienes que imaginarte; probablemente has tenido que lidiar con eso, y probablemente fue un desastre y medio, ¿no? Las compilaciones son una de las peores opciones posibles para un lenguaje de scripting declarativo, porque los problemas serios terminan rápidamente chocando con los límites de la declarativa, y los que no son lo suficientemente simples como para no necesitar una herramienta de compilación.Vamos a darte un ejemplo del mundo real.
Hace unos 15 años trabajé en portar un gran sistema escrito en C desde Unix a Windows, tenía aproximadamente 3 millones de líneas de código. Para darle una idea de la escala, se tardó más de 24 horas en compilar en algunos de nuestros sistemas Unix (RS6000), Windows podría compilar el sistema en aproximadamente 4 horas.
(También teníamos 2 millones de líneas de código en nuestro propio lenguaje interpretado, pero decidimos no usar nuestro lenguaje para los sistemas de compilación, ya que nunca fue diseñado para el procesamiento de archivos. También necesitábamos un sistema de compilación para compilar el código C que implementaba nuestro lenguaje .)
En el momento en que el sistema de compilación se escribió en una combinación de scripts de shell y archivos de creación, estos no eran portátiles para Windows, por lo tanto, decidimos escribir nuestro propio sistema de compilación.
Podríamos haber usado C, sin embargo, decidimos usar Python, había pocas razones. (También reescribimos nuestro sistema de control de código fuente en Python al mismo tiempo, esto está muy integrado con el sistema de compilación, por lo que los desarrolladores pueden compartir los archivos de objetos para los módulos registrados).
La mayor parte de nuestro código podría construirse con unas pocas reglas simples (solo unos pocos miles de líneas de python para todas las plataformas, Windows, VMS y 6 versiones de Unix) que se derivaron de las convenciones de nomenclatura de los archivos.
En ese momento, RegEx no era muy estándar entre los sistemas C en diferentes plataformas, Python había incorporado RegEx.
Algunos módulos necesitaban pasos de compilación personalizados, Python permitió que los archivos de clase se cargaran dinámicamente. Permitimos que se usara una clase personalizada para construir un módulo (lib), basado en tener el archivo python con un nombre mágico en la carpeta. Esta fue la razón asesina para usar Python.
Consideramos Java, pero en ese momento no se distribuía en todas las plataformas.
(La interfaz de usuario de nuestro sistema de control de código fuente utilizaba un navegador web, ya que era portátil en toda la plataforma. Esto fue 6 meses antes de tener una conexión a Internet. ¡Tuvimos que descargar el navegador a través de X25!)
fuente
La respuesta corta a esta pregunta es que esto es lo que es una herramienta de compilación . Una herramienta que automatiza el uso de otras herramientas, con el objetivo de construir un producto final a partir de algunos archivos fuente. Si estamos escribiendo el script de compilación en el mismo idioma que el producto en sí, estamos en el ámbito de las herramientas específicas del lenguaje, que no se considerarían herramientas de compilación de la misma manera.
Esto plantea la pregunta: ¿por qué los compiladores no proporcionan el tipo de automatización de compilación a la que estamos acostumbrados desde herramientas como make? A lo que la respuesta es simplemente porque make existe . La filosofía de Unix de "hacer una cosa y hacerlo bien" sugiere que no es responsabilidad del compilador proporcionar esto *. Dicho esto, personalmente he pasado por mi parte de hacer dolores de cabeza, y estaría interesado en probar un compilador que proporcione su propio sistema de construcción "nativo" entre comillas.
Para ver un ejemplo de un compilador diseñado de esta manera, vea el Jai de Jon Blow (aún no publicado), un lenguaje destinado a reemplazar a C ++. Aquí se recopilan enlaces a charlas y demostraciones del compilador . Este lenguaje se compila en código de bytes que se ejecuta dentro del compilador, y la compilación en binario es una función estándar proporcionada por la biblioteca, accesible desde el código de bytes. La intención es permitir tanto la automatización de compilación como la metaprogramación dentro de la sintaxis nativa del lenguaje.
* Una mirada al Visual Studio de Microsoft le mostrará un ejemplo de la filosofía opuesta. :)
fuente
La herramienta de compilación es ante todo una herramienta, al igual que 'gcc', 'ls', 'awk' o 'git'. Alimenta la herramienta con una entrada (nombre de archivo, parámetros, etc.) y hará algunas cosas en consecuencia.
Todas estas herramientas le permiten pasar su entrada de manera que sea lo suficientemente simple como para escribir y comprender. En el caso particular de las herramientas de compilación, la entrada es un archivo de receta, un archivo que describe cómo su proyecto va desde los archivos de origen hasta el producto terminado.
Si su receta es tan simple como pasar la carpeta que contiene el proyecto y el compilador a utilizar, entonces un "lenguaje" declarativo es suficiente. Una vez que la receta se vuelve más y más complicada, con más lógica, se vuelve problemático manejarla con lenguajes declarativos y se utilizan lenguajes de propósito más general.
Ahora debería ser evidente que no hay conexión entre el idioma utilizado para escribir sus recetas de compilación y los idiomas utilizados para escribir el código de su producto simplemente porque tienen diferentes propósitos y requisitos. No hay conexión ni siquiera entre el idioma en el que está escrita la herramienta de compilación y el "idioma" en el que deben escribirse las recetas de compilación. ¡Utilice siempre la mejor herramienta para el trabajo!
fuente