Приклади, коли ми будемо використовувати інтерпретовану мову над складеною мовою?


11

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

Відповіді:


11

Існує (наскільки мені відомо) не існує такого поняття, як інтерпретована "мова" чи складена "мова".

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

Тепер, якщо у вас виникає питання, коли ви використовуєте компілятор мови проти інтерпретатора мови, він дійсно зводиться до професіоналів / конвеєрів компілятора порівняно з інтерпретатором та метою проекту.

Наприклад, ви можете використовувати компілятор JRuby для легшої інтеграції з бібліотеками java замість інтерпретатора рубіну MRI. Ймовірно, є також причини використовувати інтерпретатор рубіну MRI через JRuby, я не знайомий з мовою, хоча і не можу з цим говорити.

Розрекламовані переваги перекладачів:

  • Жодна компіляція не може скоротити час від редагування коду до тестування програми
  • Не потрібно генерувати бінарні файли для декількох архітектур, оскільки інтерпретатор буде керувати абстракцією архітектури (хоча вам може знадобитися все-таки турбуватися про те, що сценарії правильно обробляють цілі розміри, тільки не двійковий розподіл)

Розрекламовані переваги компіляторів:

  • Складений нативний код не має накладних витрат на перекладача і тому зазвичай є більш ефективним у часі та просторі
  • Взаємодія є, як правило, кращою, єдиний спосіб для внутрішньої операційної взаємодії зі сценаріями - через інтерпретатор, а не стандартний FFI
  • Можливість підтримки архітектури інтерпретатора не складено (наприклад, вбудовані системи)

Однак я б став би в 90% випадків, що це щось подібне: я хочу написати це програмне забезпечення в blub, оскільки я добре його знаю, і воно повинно зробити гарну роботу. Я буду використовувати інтерпретатор blub (або компілятор), оскільки це загальноприйнятий канонічний метод для написання програмного забезпечення в blub.

Отже, TL; DR - це порівняно для кожного конкретного випадку порівняння інтерпретаторів та компіляторів для конкретного випадку використання.

Також FFI: Інтерфейс іноземних функцій, іншими словами інтерфейс для взаємодії з іншими мовами. Більше читання на wikipedia


2
Наскільки мені відомо, деякі мови сценаріїв для ОС, такі як ksh для UNIX, неможливо скласти.
NoChance

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

3
@EmmadKareem Не існує такого поняття, як "неможливо скласти". Ви пишете програму, яка читає програму мовою Li і видає еквівалентну програму мовою La. Це компілятор, компілятор. Я вагаюся, щоб посилатися на аргумент твердості про повноту, оскільки це червона оселедець на практиці, але кожна програма в кінцевому підсумку перетворюється на послідовність інструкцій машинного коду. Якщо все інше не вдалося, розгорніть цикл інтерпретатора (та спростіть отриманий код, щоб видалити деталі, які вам більше не потрібні). Якщо перекладач написаний мовою без перекладачів, повторюйте, поки ви не потрапите на компілятор.

1
(Я відредагував свій коментар, щоб висловити це краще, але, мабуть, я діяв надто пізно.) @EmmadKareem Так, очевидно, що деякі мови ніколи не були реалізовані через компілятор. Але я не бачу, наскільки це актуально. Це завжди можливо і реально зробити, і це можна зробити в будь-який час з певними зусиллями. Це є наслідком основного моменту, який полягає в тому, що мова не є ні за своєю суттю складеною, ні інтерпретованою, і може бути реалізована обома способами. І безліч інших способів (ну, мабуть, другорядних варіантів і реміксів), до речі.

2
@EmmadKareem, якщо ви хочете, можете взяти специфікацію мови ksh і написати компілятор, який прочитав би її і створив нативну бінарну. Мова, яка складається або інтерпретується, не є визначенням мови.
Джиммі Хоффа

8

Тут важливим моментом є те, що багато мовних реалізацій насправді роблять якийсь гібрид обох. Сьогодні багато часто використовуваних мов працюють, складаючи програму в проміжний формат, такий як байт-код, а потім виконуючи це в інтерпретаторі. Ось як зазвичай реалізуються Java, C #, Python, Ruby та Lua. Фактично, це, мабуть, те, як реалізована більшість використовуваних сьогодні мов. Отже, справа в тому, що мова сьогодні і інтерпретує, і складає їх код. Деякі з цих мов мають додатковий компілятор JIT для перетворення байт-коду в нативний код для виконання.

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

Коли ви питаєте про достоїнства інтерпретованих та складених мов, ви, мабуть, маєте на увазі щось інше. Ви можете запитати про достоїнство статичного / динамічного набору тексту, достоїнства розповсюдження власних виконуваних файлів, відносні переваги компіляції JIT та AOT. Це всі питання, які стикаються з інтерпретацією / складанням, але це різні питання.


2

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

Тепер, перш ніж хтось задається питанням ... Так, C / C ++ / C # / Java можна інтерпретувати, і так, сценарії JavaScript та Bash можуть бути складені. Чи є перекладачі чи компілятори для цих мов - інше питання.

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

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

Однак є щось, що можна вважати прикладом у реальному світі: вихідний код hidnig після розгортання. З ріднимСкомпільований код розробник розгортає виконуваний макін-код програми та даних. З інтерпретованим кодом повинен бути розгорнутий сам вихідний код, який потім може бути перевірений та реінжинірований з набагато меншими зусиллями, ніж те, що стосується реверсивного коду машинного коду. Єдиним винятком цього є такі мови, як C # і Java, які компілюються до прямої мови / байт-коду (MSIL для C # та Java-байт-код для Java), який потім розгортається і компілюється "вчасно" під час виконання, як і інтерпретатор. Однак існують так звані декомпілятори для MSIL та Java Bytecode, які можуть реконструювати оригінальний вихідний код з відносно хорошою точністю, і як така реверсивна інженерія таких продуктів набагато більш тривіальна, ніж продукти реверсивної інженерії, які розгорнуті в рідному машинному коді.


1
Ви робите хороші бали, але будучи педантом, який я є, я приймаю питання з деякими фразами (обидва посилаються на третій абзац): 1. Перекладач не складає. 2. Це погано (хоча ці умови рідкісні), коли поганий неоптимізуючий компілятор повинен бути побитий високооптимізованим інтерпретатором (на основі байткодного коду). Це подвоюється, якщо ви вважаєте компілятори JIT під інтерпретаторами (що я вважаю за краще не робити, але деякі люди це роблять).

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

Вибачте, ніколи не зважайте на перший пункт, я щось неправильно прочитав. Mea culpa. Щодо другого моменту: я взяв "еквівалент" для позначення інтерпретованого або компільованого коду (а порівнювати компілятор і інтерпретатор не має великого сенсу, як це роблять принципово різні речі). Я не думаю, що не варто витрачати час на деталізацію чужих випадків, як мій приклад, але я вважаю за краще відмовитись від "завжди" на користь фрази, яка пояснює, чому в першу чергу це може бути швидше: Ніяких перекладачів накладних витрат [що має бути визначено IMHO], та можливість проводити оптимізацію до виконання.

1

Я можу придумати такі сценарії, коли ви використовуєте інтерпретовану мову:

  • Там, де немає компілятора, як-от сценарії оболонки Linux / Unix .
  • Швидкі та брудні сценарії, які вирішують невелику проблему
  • Мови, які полегшують написання динамічних HTML-сторінок і інтерпретуються в основному як JSP (Tomcat компілює його в сервіс-попередження для запуску), PHP, ASP тощо.

Я можу придумати такі сценарії, коли ви хочете скласти свій код:

  • Вам потрібно розповсюджувати двійкові файли, оскільки ваш додаток із закритим кодом, і ви не хочете видавати свій вихідний код.
  • Швидкість, як вбудовані системи тощо.
  • Вам потрібен рівень безпеки типу коду, який може надати вам лише компілятор зі строго набраною мовою. Компілятори виявляють помилки друку у кожному куточку вашого вихідного коду, тоді як в інтерпретованих програмах помилки друку можуть бути нерозкритими у виробничому коді.
  • Великі , складні системи: ОС або офісний костюм не можна уявити як інше, крім складених бінарних файлів.
  • Ви хочете, щоб кожен крихітний шматочок вийшов з дороги і вам потрібна хороша комунікація з фрагментами асемблера (важко з будь-яким типом виконання, особливо з інтерпретатором) (це стосується коментаря @delnam)

3
Мовний перекладач робить мову не менш сильно набраною. Haskell надзвичайно сильно набраний, і ви можете використовувати GHCI для його ефективного тлумачення. Сильне / слабке введення тексту - це аспекти мови, а не аспекти компілятора чи перекладача.
Джиммі Хоффа

1
-1 Про плюси компіляції: (1) Компілюючий код не захищає від зворотної інженерії, він лише робить його трохи складніше. (2) Компіляція (видалення накладних витрат інтерпретатора, автоматизована оптимізація коду програми) - лише одне джерело продуктивності і перевершується ручними масштабними оптимізаціями людським експертом. (3) Перевірка типу, хоча зазвичай поєднується з компіляцією, не залежить від неї. Перевірка типу - це пропуск статичного аналізу; це може статися без випромінювання коду та перед інтерпретацією коду. (4) Здається, це дуже помилково. Ви цього "не уявляєте"? Чому? Як це потрібно?

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

3
"сценарії" не обов'язково інтерпретуються. Багато мов «скриптування» складаються для байт-коду для віртуальної машини, яка потім виконується (див. Lua, perl, python, ruby). Немає реальної різниці між цим і java, окрім випадків, коли відбувається компіляція.

3
+1, я вважаю, що саме така відповідь отримала дійсно ОП, і хоча пункти можуть бути не на 100% правдивими, як зазначалося, є принаймні 95% правдивих з практичних міркувань.
Doc Brown

1

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

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

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

Знаючи це, інтерпретовані мови підходять для:

  1. Продуктивна розробка: швидка веб-розробка (PHP, Javascript) або для прототипування.
  2. Крос-платформа; наприклад, підтримується JavaScript у кожному веб-переглядачі (включаючи мобільні браузери).

І компільовані мови підходять, коли:

  1. Продуктивність є критичною (операційні системи) або ресурсів мало (мікроконтролери).
  2. Системи, що будуються, є складними; при створенні великих систем (корпоративних систем) компільовані мови необхідні для обробки багатьох можливих помилок, які можуть з’являтися в інтерпретованих мовах; Також складні програми потребують багатьох ресурсів, і баланс також має тенденцію до складання мов.

-1 тому, що ви маєте на увазі, що всі інтерпретовані мови динамічно набираються, а всі складені мови набираються статично, що абсолютно не відповідає дійсності.
Даніель Приден

@DanielPryden Тоді повинен бути чистий збіг, той факт, що майже всі інтерпретовані мови динамічно набираються, а компільовані - статично типізовані? Чи випадково модель динамічного типу підходить для інтерпретованих мов?
m3th0dman

З різних причин існує кореляція, але це не є вимогою. Про це насправді запитували в StackOverflow: Чому інтерпретовані язики здебільшого є типовими, а компільовані мають сильний набір тексту?
Даніель Приден

1
Ерланг складається і динамічно набирається. Haskell набраний статично і може бути складений або інтерпретований
Zachary K

1
@ZacharyK Erlang має систему запуску; Haskell складається в більшості випадків (програми написані).
m3th0dman

1

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

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

Це стосується, наприклад, мов агентів, або способу, як, скажімо, Tcl / Tk зазвичай використовується.

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

Для майже будь-якого іншого можливого випадку використання компіляція (або гібридний підхід) найкраще підходить.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.