Perché java non è usato come linguaggio di costruzione?

24

Se Java è un linguaggio generico e la costruzione di un programma è qualcosa che può essere descritto usando il linguaggio Java, perché non è questo il modo migliore per scrivere i file di build e invece usiamo strumenti come Ant, Maven e Gradle ? Non sarebbe più semplice, e rimuovere anche la necessità di imparare ancora un altro linguaggio di programmazione? (A proposito, questa domanda può essere applicata anche ad altre lingue, come C #)

    
posta vainolo 25.03.2014 - 21:33
fonte

6 risposte

21

Strumento specifico per uno scopo specifico

  • Verbosità

    Le lingue di uso generale sono spesso troppo prolisse. Se dovessi gestire una build in Java, sarei molto depresso molto rapidamente dalle dimensioni della bestia. Tuttavia, potrebbe facilmente essere gestibile utilizzando una DSL scritta in Java. E in una certa misura è così che puoi vedere Gradle (per Groovy) e Buildr (per Ruby).

  • difficoltà

    Le lingue di uso generale sono difficili. Beh, non penso che la programmazione sia difficile e non possa essere ripresa da nessuno, ma il punto è: il tuo ingegnere di costruzione non è necessariamente il tuo programmatore!

  • Obiettivo

    Questo è più o meno all'incrocio tra difficoltà e verbosità . Un linguaggio è progettato per uno scopo, e qui stiamo parlando di qualcosa di molto specifico. Quindi perché dovresti o vuoi usare un linguaggio di scopo generale ? Per le build, è necessario:

    • rami e condizioni per gestire configurazioni separate, ambienti, ecc ...
    • una serie di istruzioni per estrarre i dati dal tuo ambiente,
    • un set di istruzioni per produrre risultati.

    Non ti serve davvero molto di più.

Certo è fastidioso quando il tuo sistema di compilazione sembra non essere abbastanza flessibile per quello specifico caso d'uso che stai cercando, ma probabilmente è molto meglio dell'alternativa per la maggior parte delle persone.

Questo è probabilmente il motivo per cui esiste una polarità tra le persone che preferiscono i sistemi di build dichiarativi rispetto alla maggior parte delle forze programmabili: immagino che uno sviluppatore possa avere una naturale tendenza a cercare modi per uscire dalla scatola.

Aspetta, abbiamo davvero bisogno di uno strumento?

Un'altra domanda correlata potrebbe essere: abbiamo davvero bisogno di uno strumento di costruzione? Non è il fatto che esistano in tutte le lingue il segno che riempiono un vuoto che non dovrebbe nemmeno essere lì in primo luogo?

Alcune lingue non richiedono necessariamente uno strumento di compilazione. Ad esempio, la maggior parte dei linguaggi di scripting non ne ha bisogno e si risolve al momento del caricamento. Oppure prendi Go, il cui compilatore gestirà tutto per te, il che è un bel contrappunto: e se un compilatore come gcc all'improvviso non avesse bisogno di un mucchio di flag, un linker e un makefile per morire tutto insieme? O se javac non avesse bisogno di build.xml o pom.xml per dirgli cosa fare? La gestione delle dipendenze non dovrebbe far parte direttamente degli strumenti del linguaggio, dato che le dipendenze fanno parte del programma finale?

Sembra sicuramente un approccio molto più semplice per l'utente (il costruttore). Anche se si potrebbe obiettare che stanno semplicemente facendo le cose sotto la cappa e portando via la scelta e le opportunità per influenzare quel processo di costruzione (ma poi si spera che un tale strumento permetta estensioni del compilatore e cose simili). Inoltre, eravamo abituati a vedere gli strumenti e il linguaggio come due cose separate, quindi potrebbe sembrare poco impuro vederli così strettamente accoppiati.

Non penso che la lingua che usi per creare i tuoi programmi sia un problema. È la lingua che usi per programmare e la sua piattaforma e strumenti di base che dovrebbero avere importanza, e stiamo ancora facendo progressi in questo senso.

Personalmente, ho usato make / gmake / autotools / pmk e sono stato felice con loro per C, e ho iniziato con Java quando tutto ciò che avevamo era make, quindi formica, e ora generalmente preferisco Maven a tutti questi alternative. Anche se posso vedere il valore in gradle, buildr e altri, ma mi piace la prevalenza di esperti finora, fino a quando non si verificherà un cambiamento più significativo. Inoltre ho come che è rigido, ma ti lascia comunque la possibilità di aggirare il problema se necessario. Non è facile è una buona cosa.

È uno strumento di costruzione. Impara ad abbracciarlo e non combatterlo. È una battaglia persa. O almeno molto molto lungo.

    
risposta data 26.03.2014 - 12:38
fonte
21

Java è un linguaggio imperativo , Ant , Maven , ecc. sono lingue dichiarative :

We could define the difference as follows:

  • Imperative programming: telling the "machine" how to do something, and as a result what you want to happen will happen.
  • Declarative programming: telling the "machine" what you would like to happen, and let the computer figure out how to do it.1

Costruisci linguaggi dire al costruttore cosa dovrebbe fare , da dove dovrebbe essere preso, ecc. Il motore che esegue la build ( che è scritto in un linguaggio imperativo, come ha notato @ElliottFrisch), legge queste istruzioni e le soddisfa.

Le lingue dichiarative possono sembrare più appropriate negli scenari di costruzione, poiché le attività di compilazione sono generalmente le stesse dappertutto e sono considerate più manutenibili e leggibili in tale forma rispetto a un modulo di codice completo.

    
risposta data 25.03.2014 - 21:45
fonte
4

Se si guardano le caratteristiche di un tipico sistema di build si trova:

  1. Un sacco di dati: nomi, opzioni, impostazioni, elementi di configurazione, stringhe, ecc.
  2. Un sacco di interazione con l'ambiente: comandi, variabili d'ambiente
  3. Un "motore di compilazione" relativamente semplice che gestisce le dipendenze, il threading, la registrazione ecc.

Se decidi di scrivere una serie di file build usando un linguaggio (Java / C # / Python / etc), circa la terza o quarta iterazione su cui ti accontenterai (a) mantenendo la maggior parte dei dati e comandi esterni come dati in qualcosa come XML (b) scrivendo il "motore di compilazione" nella tua lingua preferita.

Troverebbe anche utile trattare alcuni dei dati nel tuo XML come linguaggio interpretato, per attivare varie funzionalità nel motore di compilazione. Potresti anche interpretare alcune macro o eseguire sostituzioni di stringhe, nei dati.

In altre parole, avresti finito con Crea, o Ant, o Rake, o MsBuild. Un linguaggio imperativo per le cose che fa bene e strutture dati per descrivere ciò che si vuole fare, ora di solito in XML.

    
risposta data 26.03.2014 - 06:23
fonte
2

In questi casi un certo numero di fattori si contrappone all'uso di Java / C ++ / C #.

In primo luogo, dovresti compilare lo script di build prima di poterlo eseguire per creare la tua app. Come specificheresti eventuali pacchetti, flag, versioni del compilatore, percorsi degli strumenti necessari per costruire il tuo script di compilazione? Certo, potresti trovare un modo per aggirarlo, ma è molto più semplice avere una lingua che non ha bisogno di quella fase di creazione (ad es. Python) o di una lingua che il tuo strumento di creazione comprende in modo nativo.

In secondo luogo, i file di costruzione sono dati pesanti mentre Java / C ++ / C # sono molto più orientati verso la scrittura di codice e algoritmi. Java e gli amici non hanno una rappresentazione molto succinta di tutti i dati che desideri archiviare.

In terzo luogo, Java e gli amici hanno bisogno di molto standard per essere validi. Il file di build dovrebbe trovarsi all'interno di un metodo all'interno di una classe con tutte le sue importazioni. Quando si utilizza un linguaggio di scripting o un linguaggio personalizzato, è possibile evitare tutto questo standard e avere solo i dettagli di costruzione stessi.

    
risposta data 26.03.2014 - 06:46
fonte
0

In effetti! Perché non utilizzare un linguaggio potente e espressivo per un problema più complesso di quanto le persone spesso (inizialmente) pensino? Soprattutto quando le persone che affrontano il problema sono già competenti con tale linguaggio. (Costruire è il problema dei programmatori e meglio risolto dai programmatori.)

Mi sono anche posto questa domanda anni fa e ho deciso che Java è un buon linguaggio per la definizione di build, specialmente per i progetti Java. E, di conseguenza, ho iniziato a fare qualcosa al riguardo.

DISCLAIMER : in questa risposta promuovo iwant , un sistema di sviluppo che sto sviluppando. Ma dal momento che questa è una discussione opinata comunque, sono sicuro che sia ok.

Non approfondirò i vantaggi di Java (potenza ed espressività) o iwant in particolare. Se sei interessato, puoi leggere di più sulla pagina di iwant .

Invece considererò perché Java (e altri GPL) sono così prontamente liquidati come inadatti alla costruzione. Molte risposte e commenti qui sono buoni esempi di tale pensiero. Consideriamo alcuni degli argomenti tipici:

"Java è imperativo, ma le build sono definite al meglio in modo dichiarativo" , potrebbero dire.

È vero. Ma quando usi una lingua come metalinguaggio per un DSL interno , ciò che conta davvero è la sua sintassi . Anche un linguaggio imperativo come Java può essere ingannato per essere dichiarativo. Se sembra e si sente dichiarativo, è (per scopi pratici) dichiarativo. Ad esempio:

JacocoTargetsOfJavaModules.with()
    .jacocoWithDeps(jacoco(), modules.asmAll.mainArtifact())
    .antJars(TestedIwantDependencies.antJar(),
            TestedIwantDependencies.antLauncherJar())
    .modules(interestingModules).end().jacocoReport(name)

Questo è un esempio reale del progetto dimostrativo di iwant .

In realtà, confrontalo con alcuni sistemi di build dichiaratamente dichiarativi che espongono i loro utenti a verbi così imperativi come "test" o "compilazione". La dichiarazione di cui sopra contiene solo nomi, nessun verbo. La compilazione e il test sono compiti implicitamente gestiti da iwant al fine di garantire all'utente i nomi che desidera. Non è la lingua. È come lo usi.

"Java è prolisso"

Sì, un sacco di codice Java là fuori è prolisso. Ma di nuovo, non è la lingua, è come la usi. Se un'implementazione è prolissa, incapsulala dietro una bella astrazione. Molti GPL forniscono meccanismi adeguati per questo.

Immagina solo il frammento di Java sopra scritto in XML. Sostituisci le parentesi con parentesi angolari e spostale. E poi duplica la parola chiave ogni come tag di chiusura! Java come sintassi è not verbose.

(Lo so, il confronto con XML è come prendere caramelle da un bambino, ma così tante build sono state definite in XML.)

"Dovresti compilare lo script di build"

Questo è un punto valido. Tuttavia, è solo un piccolo problema tecnico da risolvere. Potrei averlo risolto usando beanshell o qualche altro interprete. Invece, l'ho risolto trattandolo come un altro problema di build e eseguendo il boot con un semplice script shell o ant che compila ed esegue un semplice bootstrapper Java.

"Java ha boilerplate"

È vero. Devi importare classi, devi menzionare "pubblico", "classe" e così via. E qui semplici DSL esterni segnano una vittoria facile iniziale.

E se il tuo progetto è così banale che questa norma è significativa, congratulazioni. Il tuo problema non è difficile e non importa come lo risolvi.

Ma molti progetti richiedono molto più della compilazione, del report di copertura e dell'imballaggio. Se lo standard di Java è accettabile per i problemi dei clienti, perché non creare problemi? Perché creare scarpe solo per i bambini degli altri?

    
risposta data 19.05.2017 - 07:08
fonte
0

Una cosa che non penso che le altre risposte abbiano affrontato è che le limitazioni e la trasparenza di questi linguaggi di costruzione sono una parte enorme di ciò che li rende utili. Prendiamo Maven, per esempio. Sì, esegue le build ma definisce anche le dipendenze. Ciò consente a un build di Maven di abbattere quelle dipendenze e guardare le loro dipendenze e così via e così via.

Considerare se ciò è stato fatto direttamente con Java. Lo strumento di creazione vedrebbe che c'è una dipendenza. Avrebbe quindi bisogno di tirare giù così altre applicazioni Java ed eseguirlo per determinare quali sono le sue dipendenze. Ma per Maven, guarda semplicemente alle dichiarazioni di dipendenza. Il file di costruzione di Maven è trasparente. Una lingua completa di Turing è inerentemente non trasparente e quindi è inferiore per alcuni scopi come questo.

    
risposta data 19.05.2017 - 17:25
fonte

Leggi altre domande sui tag