Se Java é uma linguagem de uso geral, e a criação de um programa é algo que pode ser descrito usando a linguagem Java, por que essa não é a melhor maneira de escrever arquivos de construção e, em vez disso, usamos ferramentas como Ant, Maven e Gradle? Isso não seria mais direto e também eliminaria a necessidade de aprender outra linguagem de programação? (BTW - essa pergunta também pode ser aplicada a outros idiomas, como C #)
java
c#
builds
build-system
vainolo
fonte
fonte
Respostas:
Ferramenta específica para uma finalidade específica
Verbosidade
Linguagens de uso geral geralmente são muito detalhadas. Se eu tivesse que gerenciar uma compilação em Java, ficaria muito deprimido muito rapidamente pelo tamanho da fera. No entanto, pode ser facilmente gerenciável usando uma DSL escrita em Java. E, até certo ponto, é assim que você pode ver Gradle (para Groovy) e Buildr (para Ruby).
Dificuldade
Linguagens de uso geral são difíceis. Bem, eu não acho que a programação seja difícil e não possa ser entendida por ninguém, mas o ponto é: seu engenheiro de construção não é necessariamente seu programador!
Finalidade
Isso é mais ou menos na interseção de dificuldade e verbosidade . Uma linguagem é projetada para um propósito, e aqui estamos falando de algo muito específico. Então, por que você precisaria ou desejaria usar uma linguagem de uso geral ? Para compilações, você precisa:
Você realmente não precisa de muito mais.
Claro que é chato quando seu sistema de compilação parece não ser flexível o suficiente para aquele caso de uso especial que você procura, mas provavelmente é muito melhor do que a alternativa para a maioria das pessoas.
Provavelmente é por isso que existe uma polaridade entre as pessoas que preferem sistemas declarativos de construção em detrimento da maioria das forças programáveis: acho que um desenvolvedor pode ter uma tendência natural a procurar maneiras de sair da caixa.
Espere, precisamos mesmo de uma ferramenta?
Outra pergunta relacionada seria: realmente precisamos de uma ferramenta de construção? Não é o fato de que eles existem em todas as línguas o sinal de que preenchem uma lacuna que nem deveria estar lá em primeiro lugar?
Alguns idiomas não exigem necessariamente uma ferramenta de construção. Por exemplo, a maioria das linguagens de script não precisa de uma e resolve em tempo de carregamento. Ou pegue o Go, cujo compilador cuidará de tudo para você, o que é um bom contraponto: e se um compilador como o gcc de repente não precisasse de um monte de sinalizadores, um vinculador e um makefile para deixar tudo junto? Ou se o javac não precisasse de um build.xml ou pom.xml para dizer a ele o que fazer? O gerenciamento de dependências não deve fazer parte diretamente das ferramentas do próprio idioma, pois as dependências fazem parte do programa final?
Certamente parece uma abordagem muito mais simples para o usuário (o construtor). Embora se possa argumentar que eles estão apenas se escondendo e tirando sua escolha e oportunidades de influenciar o processo de criação (mas você esperaria que essa ferramenta permita extensões do compilador e coisas semelhantes). Além disso, costumávamos ver as ferramentas e a linguagem como duas coisas separadas, então ele pode parecer impuro de repente tê-las tão fortemente acopladas.
Não acho que o idioma que você usa para criar seus programas seja o problema. É a linguagem que você usa para programar e sua principal plataforma e ferramentas que devem importar, e ainda estamos avançando nisso.
Pessoalmente, eu usei make / gmake / autotools / pmk e fiquei feliz com eles no C, e comecei com Java quando tudo o que tínhamos era make, depois ant, e agora geralmente prefiro o Maven a todas essas alternativas. Embora eu possa ver valor em gradle, buildr e outros, mas eu gosto da prevalência de maven até agora, até que ocorra uma mudança mais significativa. Além disso, eu gosto que seja rígido, mas ainda assim você terá a capacidade de contornar isso, se necessário. Que não é fácil é uma coisa boa.
É uma ferramenta de construção. Apenas aprenda a abraçá-lo e não lute contra ele. É uma batalha perdida. Ou pelo menos muito, muito longo.
fonte
Java
é um imperativo linguagem,Ant
,Maven
, etc, são declarativas línguas:As linguagens de compilação informam ao construtor o que deve ser feito, de onde deve ser tirada etc. O mecanismo que executa a compilação (escrito em uma linguagem imperativa, como o @ElliottFrisch observou), lê essas instruções e as cumpre.
Linguagens declarativas podem parecer mais apropriadas em cenários de compilação, pois as tarefas de compilação geralmente são as mesmas em todo o caso e é considerado mais fácil de manter e legível nesse formato do que no código de código completo.
fonte
Se você observar os recursos de um sistema de compilação típico, encontrará:
Se você deseja escrever uma série de arquivos de compilação usando alguma linguagem (Java / C # / Python / etc), por volta da terceira ou quarta iteração, deve optar por (a) manter a maioria dos dados e comandos externos como dados em algo como XML (b) escrevendo o "mecanismo de compilação" no seu idioma favorito.
Você também consideraria útil tratar alguns dos dados em seu XML como uma linguagem interpretada, para acionar vários recursos no mecanismo de construção. Você também pode interpretar algumas macros ou executar substituições de string nos dados.
Em outras palavras, você terminaria com Make, Ant, Rake ou MsBuild. Uma linguagem imperativa para o que faz bem e estruturas de dados para descrever o que você deseja fazer, agora geralmente em XML.
fonte
Vários fatores contam com o uso de Java / C ++ / C # nesses casos.
Em primeiro lugar, você teria que compilar seu script de construção antes de executá-lo para criar seu aplicativo. Como você especificaria pacotes, sinalizadores, versões do compilador, caminhos de ferramentas necessários para criar seu script de construção? Certamente, você pode encontrar uma maneira de contornar isso, mas é muito mais fácil ter uma linguagem que não precise dessa etapa de construção (por exemplo, python) ou uma linguagem que sua ferramenta de construção compreenda nativamente.
Em segundo lugar, os arquivos de construção são pesados, enquanto Java / C ++ / C # são muito mais voltados para a escrita de código e algoritmos. Java e amigos não têm uma representação muito sucinta de todos os dados que você deseja armazenar.
Em terceiro lugar, Java e amigos precisam de muito clichê para serem válidos. O arquivo de construção precisaria estar dentro de um método dentro de uma classe com todas as suas importações. Ao usar uma linguagem de script ou linguagem personalizada, você pode evitar todo esse clichê e ter apenas os detalhes da compilação.
fonte
De fato! Por que não usar uma linguagem poderosa e expressiva para um problema mais complexo do que as pessoas costumam pensar (inicialmente)? Especialmente quando as pessoas que enfrentam o problema já são competentes com esse idioma. (Construir é o próprio problema dos programadores e é melhor resolvido pelos programadores.)
Eu também me fiz essa pergunta anos atrás e decidi que Java é uma boa linguagem para definir builds, especialmente para projetos Java. E, como resultado, comecei a fazer algo a respeito.
AVISO LEGAL : Nesta resposta, estou promovendo o iwant , um sistema de construção que estou desenvolvendo. Mas como essa é uma discussão opinativa, tenho certeza que está tudo bem.
Não vou detalhar os benefícios do Java (poder e expressividade) ou quero especificamente. Se você estiver interessado, pode ler mais na página iwant .
Em vez disso, considerarei por que o Java (e outras GPLs) é tão prontamente descartado como inadequado para a construção. Muitas respostas e comentários aqui são bons exemplos desse pensamento. Vamos considerar alguns dos argumentos típicos:
"Java é imperativo, mas as compilações são melhor definidas de maneira declarativa" , eles podem dizer.
Verdade. Porém, ao usar uma linguagem como metalinguagem para uma DSL interna , o que realmente conta é sua sintaxe . Mesmo uma linguagem imperativa como Java pode ser enganada para ser declarativa. Se parece e parece declarativo, é (para fins práticos) declarativo. Por exemplo:
Este é um exemplo real do projeto de demonstração do iwant .
De fato, compare isso com alguns sistemas de construção supostamente declarativos que expõem seus usuários a verbos imperativos como "teste" ou "compilação". A declaração acima contém apenas substantivos, sem verbos. Compilar e testar são tarefas tratadas implicitamente por iwant, a fim de conceder ao usuário os substantivos que ele / ela deseja. Não é a linguagem. É como você o usa.
"Java é detalhado"
Sim, muitos códigos Java lá fora são detalhados. Mas, novamente, não é a linguagem, é como você a usa. Se uma implementação for detalhada, encapsule-a atrás de uma boa abstração. Muitas GPLs fornecem mecanismos adequados para isso.
Imagine o snippet Java acima, escrito em XML. Substitua parênteses por colchetes angulares e mova-os. E duplique cada palavra - chave como uma tag de fechamento! Java como uma sintaxe não é detalhado.
(Eu sei, comparar com XML é como pegar doces de um bebê, mas muitas compilações são definidas em XML.)
"Você precisaria compilar seu script de construção"
Este é um ponto válido. No entanto, é apenas um pequeno problema técnico a ser resolvido. Eu poderia ter resolvido isso usando casca de feijão ou algum outro intérprete. Em vez disso, resolvi-o tratando-o como apenas mais um problema de compilação e iniciando o boot com um simples shell ou script ant que compila e executa um bootstrapper Java simples.
"Java tem clichê"
Verdade. Você precisa importar classes, mencionar "public", "class" e assim por diante. E aqui DSLs externos simples obtêm uma vitória fácil inicial.
E se o seu projeto é tão trivial que esse padrão é significativo, parabéns. Seu problema não é difícil e realmente não importa como você o resolve.
Mas muitos projetos precisam muito mais do que compilação, relatório de cobertura e embalagem. Se o padrão do Java é aceitável para os problemas dos clientes, por que não criar problemas? Por que fazer sapatos apenas para os filhos dos outros?
fonte
Uma coisa que não acho que as outras respostas tenham abordado é que as limitações e a transparência dessas linguagens de construção são uma grande parte do que as torna úteis. Vamos pegar o Maven, por exemplo. Sim, ele executa compilações, mas também define dependências. Isso permite que uma compilação do Maven abaixe essas dependências e veja suas dependências e assim por diante.
Considere se isso foi feito diretamente com Java. A ferramenta de construção verificaria que há uma dependência. Seria necessário puxar para baixo outro aplicativo Java e executá-lo para determinar quais são suas dependências. Mas para o Maven, ele simplesmente analisa as declarações de dependência. O arquivo de compilação do maven é transparente. Uma linguagem completa de Turing é inerentemente não transparente e, portanto, é inferior para alguns propósitos como este.
fonte