Чому java не використовується як мова побудови?


24

Якщо Java - мова загального призначення, а побудова програми - це те, що можна описати за допомогою мови Java, чому це не найкращий спосіб написання файлів складання, а натомість ми використовуємо такі інструменти, як Ant, Maven та Gradle? Хіба це не було б простіше, а також зніме необхідність вивчити ще одну мову програмування? (BTW - це питання також може бути застосовано до інших мов, наприклад, C #)


7
У вас може бути трохи цікавіше питання про те, "чому для побудови мов не використовуються мови загального призначення" - я маю на увазі, і C не є мовою збірки. Я б також запропонував переглянути церемонію навколо збирання одного файлу .java на Java

8
Це, ймовірно, може бути узагальнено як "Навіщо турбуватися з DSL?"
FrustratedWithFormsDesigner

1
Краще питання може бути; Чому IDE / компілятори / інструменти настільки погані, що інструменти для побудови потрібні в першу чергу.
Брендан

6
@Brendan це не питання, оскільки інструменти збирання та IDE служать різним цілям.
jwenting

1
Оскільки мови загального призначення ніколи не повинні використовуватися замість чітко визначених, простих мов, що залежать від домену. І якщо потреба у вивченні "ще однієї мови програмування" стосується вас, ви не повинні насправді займатися програмуванням, спробуйте іншу справу.
SK-логіка

Відповіді:


21

Конкретний інструмент для конкретного призначення

  • Багатослівність

    Мови загального призначення часто занадто багатослівні. Якби мені довелося керувати збіркою на Яві, я був би дуже пригнічений за розміром звіра. Однак це може бути легко керовано за допомогою DSL, написаного на Java. І певною мірою саме так ви можете бачити Gradle (для Groovy) і Buildr (для Ruby).

  • Складність

    Мови загального призначення важкі. Добре, я не думаю, що програмування важке і його ніхто не може підхопити, але справа в тому, що ваш інженер-конструктор не обов’язково ваш програміст!

  • Призначення

    Це більш-менш на перетині складності та багатослівності . Мова розрахована на мету, і тут ми говоримо про щось дуже специфічне. Тож навіщо вам потрібно чи хочете використовувати мову загального призначення? Для складання потрібні:

    • гілки та умовні умови для обробки окремих конфігурацій, середовищ тощо.
    • набір інструкцій для отримання даних із вашого оточення,
    • набір інструкцій для отримання результатів.

    Вам насправді не потрібно набагато більше.

Звичайно, це дратує, коли ваша система складання здається, що вона недостатньо гнучка для того випадку, який ви шукаєте, але це, мабуть, набагато краще, ніж альтернатива для більшості людей.

Це, мабуть, тому між людьми, які віддають перевагу декларативним системам побудови над більшості програмованих кроків, існує полярність: я думаю, у розробника може бути природна тенденція шукати шляхи виходу з коробки.

Зачекайте, чи нам справді потрібен інструмент?

Іншим пов'язаним питанням було б: чи нам справді потрібен інструмент збирання? Чи не факт, що вони існують на всіх мовах, є ознакою того, що вони заповнюють прогалину, яка навіть не повинна бути там в першу чергу?

Для деяких мов не обов'язково потрібен інструмент збирання. Наприклад, більшість мов скриптів не потрібна і розв’язується під час завантаження. Або візьміть Go, чий компілятор буде обробляти все за вас, що є приємним контрапунктом: а що, якщо компілятору на зразок gcc раптом не знадобиться купа прапорів, linker та makefile, щоб все разом померти? Або якщо javac не знадобився build.xml або pom.xml, щоб сказати йому, що робити? Чи не повинно управління залежністю безпосередньо бути частиною власного інструментарію мови, оскільки залежності є частиною остаточної програми?

Користувачеві (будівельнику) це, звичайно, здається набагато простішим підходом. Хоча можна стверджувати, що вони просто працюють під кришкою і забирають ваш вибір та можливості впливати на процес збирання (але тоді ви сподіваєтесь, що такий інструмент дозволяє розширювати компілятори та подібні речі). Плюс ми звикли бачити інструменти та мову як дві окремі речі, тому він може здатися незрозумілим, щоб раптом їх так щільно з'єднати.

Я не думаю, що мова, яку ви використовуєте для створення своїх програм, не є проблемою. Це мова, якою ви користуєтесь для програмування, і її основна платформа та інструменти, які мають мати значення, і ми все ще просуваємось у цьому.


Особисто я використовував make / gmake / autotools / pmk і був задоволений ними для C, і я почав з Java, коли все, що у нас було, було зроблено, а потім мурашник, і тепер я, як правило, віддаю перевагу Maven над усіма цими альтернативами. Хоча я бачу цінність у gradle, builder та інших, але мені подобається поширеність Maven поки що, поки не відбудеться більш суттєвий зсув. Плюс мені подобається, що він жорсткий, але все ж залишає у вас можливість обійти це, якщо потрібно. Те, що це не просто, - це добре.

Це інструмент побудови. Просто навчіться приймати його і не боротися з ним. Це програшний бій. Або принаймні дуже-дуже довгий.


Дійсно, як ваш прагматизм. Моє запитання викликає цікавість. Я використовую maven (раніше використовував make and мураш), і він робить "чорну магію", яка іноді є доброю, а іноді поганою. Але це все-таки магія.
vainolo

1
"Або якщо javac не знадобився build.xml або pom.xml, щоб сказати йому, що робити?" - хе. цього не відбувається і ніколи не робилося.
користувач253751

@immibis: це дискусійно. Мені б не сподобалося будувати свої проекти в офісі лише з javac :) Це, безумовно, вимагатиме справедливого трохи клею або з Makefile, або зі скриптом оболонки, або, принаймні, псевдонімами оболонки, щоб зібрати речі разом. Або гігантська програма з усім, що знаходиться в одній папці, і всіма депами в репо. Насправді не те, що мені хотілося б! :) Але це ще одна суперечка цілком, не пов'язана з питанням ОП.
хайлем

Інтеграція системи побудови з мовою також є проблемою для поліглот-проектів. Якщо я використовую обидві мови A і B і хочу мати єдиний процес збирання для них, яку систему складання мови я використовую?
Себастьян Редл

@SebastianRedl Отже, як полегшити проблему, ввівши третю мову? Просто виберіть мову, яка краще працює для вас. (І звичайно, якщо вам потрібна третя мова, Java може бути і нею.)
Віль Ойкарінен

21

Javaє обов'язковим мовою, Ant, Mavenі т.д., декларативні мови:

Ми могли б визначити різницю так:

  • Імперативне програмування: розповісти «машині», як щось робити, і в результаті відбудеться те, що ви хочете, щоб сталося.
  • Декларативне програмування: сказати «машині», що ви хочете, щоб це сталося, і дозвольте комп’ютеру зрозуміти, як це зробити. 1

Мови побудови повідомляють будівельникові, що слід робити, звідки його слід взяти і т. Д. Двигун, який запускає збірку (написаний обов'язковою мовою, як @ElliottFrisch зазначив), читає ці інструкції та виконує їх.

Мови декларацій можуть здатися більш підходящими у сценаріях складання, оскільки завдання побудови, як правило, однакові в усьому світі, і вважається, що в цій формі є більш доступними та читаними, ніж у повноцінній формі коду.


3
Існує хоча б одна система побудови, яка використовує імперативну мову. Сконс ​​використовує Python.
user16764

Це зробити імперативом не складніше, ніж написання класу, який може містити список залежностей, і спосіб їх усунення. Я підозрюю, що є інша причина --- наприклад, час запуску JVM, можливо.

2
@Lee: Майже всі інструменти збирання, що використовуються у світі Java (Ant, Maven, Gradle, SBT,…), також зазвичай працюють на JVM (за винятком Rake, Buildr або Scons, які можуть , але не мають для запуску на JVM).
Йорг W Міттаг

6
@vainolo "Більшість людей насправді не люблять Ant / Maven / Make"? Це сміливе твердження!
Бен Турлі

1
@BenThurley Мені подобалося робити люди, чому був створений мураш? і якщо мураха сподобався, чому мавен? А тепер чому люди користуються Gradle? Але я погоджуюся, що це сміливе твердження, і воно підкріплене лише "анекдотичними" доказами деяких десятків розробників Java
vainolo

4

Якщо ви подивитеся на особливості типової системи побудови, ви знайдете:

  1. Багато даних: імена, комутатори, налаштування, елементи конфігурації, рядки тощо
  2. Багато взаємодії з середовищем: команди, змінні середовища
  3. Відносно просто "побудувати двигун", обробляючи залежності, нарізування різьби, ведення журналів тощо.

Якщо ви вирішили написати серію файлів складання з використанням якоїсь мови (Java / C # / Python / тощо), приблизно на третю чи четверту ітерацію ви б вирішили: (a) зберігати більшість даних і зовнішніх команд як дані в чомусь як XML (b) написання "механізму побудови" на вашій улюбленій мові.

Вам також буде корисно поводитися з деякими даними у вашому XML як інтерпретована мова, щоб запустити різні функції в двигуні збірки. Ви також можете інтерпретувати в даних деякі макроси або виконувати підстановку рядків.

Іншими словами, ви б закінчили з Make, або Ant, або Rake, або MsBuild. Обов'язковою мовою для тих, хто добре працює, та структурами даних, які описують те, що ви хочете робити, зазвичай зараз у XML.


2

Ряд факторів не враховує використання Java / C ++ / C # у цих випадках.

По-перше, вам доведеться скласти свій сценарій збірки, перш ніж ви зможете запустити його для створення програми. Як би ви вказали будь-які пакети, прапори, версії компілятора, шляхи інструментів, необхідні для створення сценарію складання? Звичайно, ви можете придумати його шлях, але набагато простіше мати мову, яка не потребує цього кроку збирання (наприклад, python), або мову, яку ваш інструмент збирання спочатку розуміє.

По-друге, файли збірки важкі, тоді як Java / C ++ / C # набагато більш орієнтовані на написання коду та алгоритмів. Java та друзі не мають дуже короткого представлення всіх даних, які ви хочете зберегти.

По-третє, Java та друзі потребують великої кількості шаблонів, щоб бути дійсними. Файл збірки повинен бути в методі всередині класу з усім його імпортом. Використовуючи мову сценаріїв або користувацьку мову, ви можете уникнути всіх цих панелей і просто мати самі деталі збірки.


0

Справді! Чому б не використати потужну та виразну мову для проблеми, яка є більш складною, ніж часто (спочатку) думають люди? Особливо, коли люди, які стикаються з проблемою, вже володіють такою мовою. (Побудова - це власна проблема програмістів і найкраще вирішується програмістами.)

Я також задав собі це питання років тому і вирішив, що Java - це хороша мова для визначення збірок, особливо для проектів Java. І, як результат, я почав щось із цим робити.

ВІДМОВА : В цій відповіді я просуваю iwant , систему побудови, яку я розвиваю. Але оскільки це все-таки суперечлива дискусія, я впевнений, що це нормально.

Я не буду детальніше пояснювати переваги Java (потужність та виразність) або конкретно iwant. Якщо вас цікавить, ви можете прочитати більше на сторінці iwant .

Натомість я подумаю, чому Java (та інші GPL) так легко відхиляються як непридатні для побудови. Тут багато відповідей та коментарів - хороші приклади такого мислення. Розглянемо деякі типові аргументи:

"Java є обов'язковою, але збірки найкраще визначати декларативно" , можуть сказати вони.

Правда. Але при використанні мови як метамовлення для внутрішнього DSL важливим є синтаксис . Навіть така імперативна мова, як Java, може бути хитрою, щоб бути декларативною. Якщо це виглядає і виглядає декларативним, це (для практичних цілей) декларативне. Наприклад:

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

Це справжній приклад з демонстраційного проекту iwant .

Фактично, порівняйте це з деякими нібито декларативними системами побудови, які піддають своїх користувачів таким імперативним дієсловам, як "тест" або "компілювати". Вищенаведена декларація містить лише іменники, не дієслова. Складання та тестування - це завдання, які iwant неявно обробляє, щоб надати користувачеві іменники, які він хоче. Це не мова. Це як ви цим користуєтеся.

"Java є багатослівною"

Так, багато коду Java там є багатослівним. Але знову ж таки, це не мова, а те, як ви її використовуєте. Якщо реалізація є багатослівною, просто інкапсулюйте її за приємною абстракцією. Багато GPL надають адекватні механізми для цього.

Просто уявіть наведений вище фрагмент Java, написаний у XML. Замініть дужки на кутові дужки та перемістіть їх. А потім дублюйте кожне ключове слово як завершальний тег! Java як синтаксис не є багатослівним.

(Я знаю, порівнювати з XML - це як брати цукерки у дитини, але так багато складених випадків визначаються в XML.)

"Вам доведеться скласти сценарій збірки"

Це дійсний пункт. Тим не менше, це лише незначна технічна проблема, яку потрібно вирішити. Я міг би вирішити це, використовуючи бобше або інший перекладач. Натомість я вирішив це, розглядаючи його як лише чергову проблему збірки та завантажуючи iwant за допомогою простого сценарію оболонки чи мурашника, який компілює та запускає простий завантажувач Java.

"У Java є котлован"

Правда. Ви повинні імпортувати класи, ви повинні згадати "public", "class" тощо. І ось прості зовнішні DSL отримують початковий простий виграш.

І якщо ваш проект настільки банальний, що ця котяча панель є важливою, вітаю. Ваша проблема не є складною, і насправді не має значення, як ви її вирішите.

Але для багатьох проектів потрібно набагато більше, ніж складання, звіт про покриття та упаковка. Якщо котлован Java прийнятний для клієнтів, чому б не створити проблеми? Навіщо робити взуття тільки для чужих дітей?


0

Я не думаю, що інші відповіді стосуються того, що обмеження та прозорість цих мов складання є величезною частиною того, що робить їх корисними. Візьмемо, наприклад, Мейвен. Так, він виконує збірки, але також визначає залежності. Це дозволяє будувати Maven, щоб знищити ці залежності і подивитися на їх залежності тощо і так далі.

Подумайте, чи це було зроблено безпосередньо з Java. Інструмент збирання бачить, що існує залежність. Тоді потрібно буде зняти таку іншу програму Java та виконати її, щоб визначити, що це за залежності. Але для Maven він просто розглядає декларації залежності. Файл збірки Maven прозорий. Повна мова Тюрінга за своєю суттю непрозора, а тому поступається деяким цілям, таким як ця.


Як в цьому вписується Gradle? Він визначає залежності в декларативному стилі, використовуючи мову загального призначення (Groovy). У інструменті на основі Groovy, JavaScript або Lisp природно використовувати компілятор мови або інтерпретатор для розбору декларацій, будь то просто їх читати чи 'виконувати' (застосувати певну функцію). Ця подвійність коду та даних не є частиною загальноприйнятої ідіоми Java, хоча й не неможливою. Забезпечення повноти не перешкоджає гарному представленню даних. Це відкриває можливість, що ваші дані зроблять те, чого ви цього не очікували.
joshp

@joshp Я не знайомий з Gradle. Це описується як DSL, і речі виглядають досить декларативно. Базуючись на Groovy, не обов'язково означає, що він є рівноцінним Groovy за своєю силою. Вам, мабуть, вдасться сказати, чи насправді Градле є мовою повного Тюрінга. Приклади залежності, які я розглянув, здаються досить простими. Чи можете ви використовувати довільні вирази Groovy у таких речах, як декларації залежності?
JimmyJames

Особисто мені навіть не подобаються перехідні залежності. Часто вони просто викликають сюрпризи в класі (кілька несумісних версій бібліотек). Ось чому в maven є елемент виключення, але клопоту не просто варто. Явні залежності роблять життя простішим. Тим не менш, транзитивні залежності можуть бути реалізовані з Java. Я зробив щось подібне з iwant , повторно використовуючи побудову визначень інших проектів.
Віль Ойкарінен

@VilleOikarinen Я, мабуть, з вами згідний. Я думаю, що це також спричиняє тонну набряку, оскільки не виникає жодних витрат на те, щоб залучити більше залежностей, навіть якщо ти їх не використовуєш. Однак у контексті цієї відповіді я не коментую значення чи мудрість цієї функції, а те, наскільки використання DSL корисне для її досягнення.
JimmyJames

1
@VilleOikarinen Я думаю, що ми наче досягли кінця цього, але я просто хочу уточнити, що я не кажу про pom / maven. Це приклад побудови DSL, але я дуже не думаю про це. Я використовую це нахабно і думаю, що це незграбно. Але що є домінантою пам’яті, це декларації залежності. Я деякий час використовував Buildr, і він читав пом для залежностей, але він не використовує їх для специфікацій збірки. Існує ряд інструментів, які не базуються на Java, які розуміють цю пам’ять, але AFAIK. Їх важливо лише залежність.
JimmyJames
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.