Por que as ferramentas de construção usam uma linguagem de script diferente da linguagem de programação subjacente?


23

Recentemente, tenho usado algumas ferramentas de construção para um projeto Nodejs em funcionamento quando percebi que a ferramenta / sistema de construção principal da maioria das linguagens usa uma linguagem diferente da própria linguagem de programação subjacente.

Por exemplo, o make não usa C ou C ++ para escrever scripts e o ant (nem o Maven) não usa Java como sua linguagem para scripts.

Idiomas mais recentes como Ruby usam a mesma linguagem para criar ferramentas como rake , o que faz sentido para mim. Mas por que nem sempre foi esse o caso? Qual é a vantagem de ter uma ferramenta de construção que usa um idioma diferente do idioma subjacente?


14
Talvez a linguagem de uso geral não seja adequada o suficiente para o uso especializado da ferramenta? Por exemplo, eu não gostaria de escrever arquivos make em C! Às vezes, uma DSL é melhor.
Andres F.

13
Olhe de outro ângulo: por que não usar make para escrever software aplicativo?
whatsisname 21/09/15

4
Este artigo é principalmente sobre o que o autor acredita que torna o Lisp ótimo, mas tem algumas informações relevantes sobre o motivo pelo qual o Ant usa XML em vez de Java.
8bittree

6
Se você quisesse escrever um programa em C que automatize a criação de programas em C, você não acabaria escrevendo makenovamente (que é implementado em C de qualquer maneira)?
Brandin

6
@ joshin4colours make está escrito em C. A linguagem que faz usos, no entanto, é uma linguagem declarativa que chama o shell conforme necessário.

Respostas:


36

A escolha de qual linguagem de programação usar para realizar qualquer tarefa deve depender dos recursos específicos desse objetivo e não das outras tarefas relacionadas a esse projeto.

Uma ferramenta de construção executa um trabalho muito específico e, independentemente do idioma que você está usando para o projeto principal, uma ferramenta de construção é um software por si só.

Tentar amarrar o projeto principal e sua ferramenta de construção pode ser uma péssima decisão. O que você precisa com uma ferramenta de construção é principalmente um processo rápido de regras simples, com um gerenciamento rápido de arquivos e E / S.

Se linguagens como o ruby ​​se usam para implementar sua ferramenta de construção, está mais relacionado aos recursos dessa linguagem do que à necessidade assumida de manter tudo escrito na mesma linguagem.


18

Não é impossível escrever uma ferramenta de construção que use uma linguagem como C ou Java como linguagem de script. No entanto, as ferramentas de construção se beneficiam do uso de linguagens de script mais declarativas . Imagine a dor e a clichê de escrever um makefile (ou build.xml, ou o que for) em C.

As ferramentas de construção se beneficiam do uso de DSLs, uma tarefa para a qual C não é uma escolha particularmente boa. C é geral demais para uma ferramenta de construção e muito preocupado com detalhes propensos a erros e de baixo nível. Por exemplo, você não deseja se preocupar com gerenciamento explícito de memória em uma ferramenta de construção! Portanto, mesmo se você estiver usando sintaxe do tipo C, provavelmente usará a coleta de lixo em sua ferramenta de script. Nesse ponto, por que não usar simplesmente uma DSL dedicada?

Faz sentido que Ruby possa ser usado para isso, pois é uma linguagem mais declarativa e de nível superior que C ou Java. Veja também: Gradle, sbt.


13
Imagine the pain and boilerplate of writing a makefile (or build.xml, or whatever) in C.Imagine a dor e a bagunça de tentar expressar lógica condicional não trivial (você sabe, coisas imperativas padrão) em um script XML declarativo. Oh, espere, você não precisa imaginar; você provavelmente já teve que lidar com isso, e provavelmente foi uma bagunça e meia, não foi? Construções são uma das piores opções possíveis para uma linguagem de script declarativa, porque problemas sérios acabam se chocando com os limites da declaratividade e aqueles que não são simples o suficiente para não precisar de uma ferramenta de construção.
Mason Wheeler

7
@MasonWheeler Há casos em que as ferramentas de compilação existentes me fizeram sofrer, sim. Nenhum deles teria sido ajudado usando uma linguagem imperativa de baixo nível do tipo C. Eu vejo algo como Ruby como provavelmente ideal: declarativo e imperativo o suficiente, conforme necessário. C me daria pesadelos para esta tarefa. Para mim, construir sistemas é um bom caso de uso para (principalmente) DSLs declarativas: você se importa com o que fazer, não com o que fazer (na maioria das vezes).
Andres F.

2
Justo. Eu sempre achei que C é uma daquelas tecnologias "se X é a resposta que você está fazendo a pergunta errada", para ser perfeitamente honesto; é que trabalhar com "scripts" XML tem sido um pesadelo toda vez que tive que mergulhar em um. Concordo que uma linguagem imperativa de nível superior com recursos DSL seria ideal.
Mason Wheeler

@AndresF .: Coisas como criar arquivos requerem uma mistura de abordagens. O estado de saída desejado é especificado declarativamente, mas as ações necessárias para atingir esse estado são especificadas imperativamente.
Supercat

1
@MasonWheeler Acho que isso é um problema tanto das pessoas que criaram a linguagem de configuração quanto o próprio XML. O erro comum dos autores de tais linguagens é supor que apenas porque algo está em XML, ele será automaticamente legível por humanos. (Eu sei que cometi esse erro mais vezes do que me sinto confortável. É tão tentador.) Uma linguagem de configuração enxuta e bem projetada pode funcionar tão bem quanto XML quanto em qualquer outra forma.
precisa saber é o seguinte

12

Vamos dar um exemplo do mundo real.

Cerca de 15 anos atrás, eu trabalhei na portabilidade de um grande sistema escrito em C do Unix para o Windows, eram cerca de 3 milhões de linhas de código. Para você ter uma idéia da escala, demorou 24 horas para compilar em alguns de nossos sistemas unix (RS6000), o Windows pode compilar o sistema em cerca de 4 horas.

(Também tínhamos 2 milhões de linhas de código em nossa própria linguagem interpretada, mas decidimos não usar nossa linguagem para os sistemas de compilação, pois ela nunca foi projetada para processamento de arquivos. Também precisamos de um sistema de compilação para compilar o código C que implementou nossa linguagem. .)

No momento em que o sistema de compilação foi gravado em uma mistura de scripts de shell e arquivos de criação, eles não eram portáveis ​​para o Windows - portanto, decidimos escrever nosso próprio sistema de compilação.

Poderíamos ter usado C, no entanto, decidimos usar python, havia poucas razões. (Também reescrevemos nosso sistema de controle de código-fonte em python ao mesmo tempo, isso foi muito atualizado com o sistema de compilação, para que os arquivos de objetos dos módulos registrados possam ser compartilhados pelos desenvolvedores.)

  • A maior parte do nosso código pode ser construída com algumas regras simples (apenas alguns milhares de linhas de python para todas as plataformas, Windows, VMS e 6 versões do Unix) que foram derivadas das convenções de nomenclatura dos arquivos.

  • Na época, o RegEx não era muito padrão entre os sistemas C em plataformas diferentes, o Python havia incorporado o RegEx.

  • Alguns módulos precisavam de etapas de construção personalizadas, o Python permitiu que os arquivos de classe fossem carregados dinamicamente. Permitimos que uma classe personalizada fosse usada para criar um módulo (lib), com base no arquivo python com um nome mágico na pasta. Essa foi a razão mais importante para usar o python.

  • Consideramos o Java, mas não estava sendo distribuído em todas as plataformas naquele momento.

(A interface do usuário do nosso sistema de controle de código-fonte usava um navegador da Web portátil em toda a plataforma. Isso ocorreu seis meses antes de termos uma conexão com a Internet. Tivemos que fazer o download do navegador pelo X25!)


Tendo trabalhado em vários sistemas bigish, às vezes sinto que tenho uma noção de como o desenvolvimento é escalável. Então eu li histórias assim. Sheesh.
precisa saber é o seguinte

@immibis Essa foi a moda de se fazer há 15 anos. Ainda mais, essa prática foi realmente aprovada e incentivada pelos principais fornecedores de Unix (SGI e DEC em particular, mas também a IBM).
oakad

1
As pessoas tendem a esquecer que o Unix costumava significar "caro". O Windows venceu a guerra de desktop / estação de trabalho por ser mais barato. É pela mesma razão que o Linux venceu mais tarde a guerra dos servidores.
slebetman 22/09/2015

1
Se eu quero que um computador execute o software que eu mesmo escrevi, quero que ele seja flexível e tenha 101 opções de como os kernels são compilados etc. No entanto, se eu estiver vendendo software para ser instalado no computador do cliente, quero que ele seja executando um sistema operacional que não seja flexível, para que eu saiba que funcionará no computador deles se funcionar no meu. Esse foi um grande fator ao considerar o Linux como fornecedor de software - o suporte parecia muito caro. O Linux venceu as guerras de software de servidor hospedado , onde o servidor é fornecido pelo fornecedor do software - por exemplo, a maioria dos softwares implantados na Web.
Ian

3
@slebetman É justo - o Unix venceu a "guerra" anterior por ser mais barato (comparado ao LISPM e máquinas similares). Era absolutamente horrível, terrivelmente projetado e travava constantemente (mas inicializa muito mais rápido que um LISPM!: P), usando C como linguagem de programação principal (queda bastante do LISP e similares), mas era muito mais barato. De fato, muitos o adotaram porque era gratuito (houve muitas mutações livres muito antes do Linux). Na verdade, eu conheci muitos LISPers da velha escola que preferiam o MS-DOS aos unixes da época. Sim, isso é horrível.
Luaan 22/09/15

3

A resposta curta para essa pergunta é que é isso que é uma ferramenta de construção . Uma ferramenta que automatiza o uso de outras ferramentas, com o objetivo de criar um produto final a partir de alguns arquivos de origem. Se estivermos escrevendo o script de construção no mesmo idioma que o próprio produto, estaremos no domínio das ferramentas específicas do idioma, que não seriam consideradas ferramentas de construção da mesma maneira.

Isso levanta a questão - por que os compiladores não fornecem o tipo de automação de construção que estamos acostumados a partir de ferramentas como make? Para qual a resposta é simplesmente porque o make existe . A filosofia do Unix de "faça uma coisa e faça bem" sugere que não é responsabilidade do compilador fornecer isso *. Dito isto, eu pessoalmente passei por minha parte de dores de cabeça e estaria interessado em experimentar um compilador que fornece seu próprio sistema de criação "nativo" entre aspas.

Para um exemplo de um compilador projetado dessa maneira, consulte o Jai de Jon Blow (ainda não lançado), uma linguagem destinada a substituir o C ++. Links para palestras e demonstrações do compilador são coletados aqui . Essa linguagem é compilada no código de bytes executado no compilador, sendo que a compilação no binário é uma função fornecida pela biblioteca padrão, acessível a partir do código de bytes. A intenção é permitir a automação de compilação e a metaprogramação na sintaxe nativa da linguagem.

* Uma olhada no Visual Studio da Microsoft mostrará um exemplo da filosofia oposta. :)


2

A ferramenta de construção é antes de tudo uma ferramenta, assim como 'gcc', 'ls', 'awk' ou 'git'. Você alimenta a ferramenta com uma entrada (nome do arquivo, parâmetros, etc.) e ela fará algumas coisas de acordo.

Todas essas ferramentas permitem que você insira suas informações de maneiras que sejam simples o suficiente para serem escritas e entendidas. No caso específico de ferramentas de construção, a entrada é um arquivo de receita, um arquivo que descreve como o seu projeto vai dos arquivos de origem ao produto final.

Se sua receita é tão simples quanto passar na pasta que contém o projeto e o compilador a ser usado, uma "linguagem" declarativa é suficiente. Uma vez que a receita se torna cada vez mais complicada, com mais lógica, torna-se problemático lidar com ela com linguagens declarativas e são usadas linguagens de propósito mais geral.

Agora deve ficar claro que não há conexão entre o idioma usado para escrever suas receitas de compilação e os idiomas usados ​​para escrever o código do produto simplesmente porque eles têm objetivos e requisitos diferentes. Não existe conexão, mesmo entre o idioma em que a ferramenta de compilação está escrita e o "idioma" em que as receitas de compilação devem estar escritas. Sempre use a melhor ferramenta para o trabalho!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.