Які переваги та обмеження мов динамічного типу порівняно з мовами статичного типу?
Дивіться також : що з любов'ю до динамічних мов (куди більш аргументована тема ...)
Які переваги та обмеження мов динамічного типу порівняно з мовами статичного типу?
Дивіться також : що з любов'ю до динамічних мов (куди більш аргументована тема ...)
Відповіді:
Здатність інтерпретатора виводити перетворення типів і типів робить час розробки швидшим, але він також може спровокувати збої під час виконання, які ви просто не можете отримати на статично набраній мові, де ви їх ловите під час компіляції. Але хто краще (або навіть якщо це завжди правда), в наші дні гаряче обговорюється (і з давніх часів).
Хороший досвід у вирішенні цього питання - це статичне друкування, де це можливо, динамічне набір тексту, коли це потрібно: кінець холодної війни між мовами програмування Еріка Мейєра та Пітера Дрейтона в Microsoft:
Прихильники статичного набору тексту стверджують, що до переваг статичного введення входить попереднє виявлення помилок програмування (наприклад, запобігання додавання цілого числа до булевого типу), краща документація у вигляді підписів типів (наприклад, включення кількості та типів аргументів при вирішенні імен), тощо можливості оптимізації компілятора (наприклад, заміна віртуальних викликів прямими дзвінками, коли точний тип приймача відомий статично), підвищення ефективності виконання (наприклад, не всі значення повинні носити динамічний тип) та кращий досвід розробника часу (наприклад, знаючи тип приймача, IDE може представити спадне меню всіх застосованих членів). Фанатики статичного набору тексту намагаються змусити нас повірити, що "добре набрані програми не можуть піти не так". Хоча це, безумовно, звучить вражаюче, це доволі вакуумне твердження. Статична перевірка типу - це абстрагування часу компіляції поведінки виконання програми вашої програми, а значить, вона обов'язково лише частково звукова та неповна. Це означає, що програми все ще можуть піти не так через властивості, які не відстежуються засобом перевірки типу, і що є програми, які, хоча вони не можуть помилитися, не можуть бути перевірені типом. Імпульс статичної типізації менш частковим і більш повним викликає типові системи надмірно складні та екзотичні, про що свідчать такі поняття, як "фантомні типи" [11] та "типові типи" [10]. Це схоже на спробу пробігти марафон із м’ячем і ланцюжком, прив’язаними до ноги, і переможно кричачи, що ви майже досягли цього, хоч ви спасалися після першої милі. Статична перевірка типу - це абстрагування часу компіляції поведінки виконання програми вашої програми, а значить, вона обов'язково лише частково звукова та неповна. Це означає, що програми все ще можуть піти не так через властивості, які не відстежуються засобом перевірки типу, і що є програми, які, хоча вони не можуть помилитися, не можуть бути перевірені типом. Імпульс статичної типізації менш частковим і більш повним викликає типові системи надмірно складні та екзотичні, про що свідчать такі поняття, як "фантомні типи" [11] та "типові типи" [10]. Це схоже на спробу пробігти марафон із м’ячем і ланцюжком, прив’язаними до ноги, і переможно кричачи, що ви майже досягли цього, хоч ви спасалися після першої милі. Статична перевірка типу - це абстрагування часу компіляції поведінки виконання програми вашої програми, а значить, вона обов'язково лише частково звукова та неповна. Це означає, що програми все ще можуть піти не так через властивості, які не відстежуються засобом перевірки типу, і що є програми, які, хоча вони не можуть помилитися, не можуть бути перевірені типом. Імпульс статичної типізації менш частковим і більш повним викликає типові системи надмірно складні та екзотичні, про що свідчать такі поняття, як "фантомні типи" [11] та "типові типи" [10]. Це схоже на спробу пробігти марафон із м’ячем і ланцюжком, прив’язаними до ноги, і переможно кричачи, що ви майже досягли цього, хоч ви спасалися після першої милі. а значить, це обов'язково лише частково звучно і неповно. Це означає, що програми все ще можуть піти не так через властивості, які не відстежуються засобом перевірки типу, і що є програми, які, хоча вони не можуть помилитися, не можуть бути перевірені типом. Імпульс статичного типізації менш частковим і більш повним викликає типові системи надмірно складні та екзотичні, про що свідчать такі поняття, як "фантомні типи" [11] та "типові типи" [10]. Це схоже на спробу пробігти марафон із м’ячем і ланцюжком, прив’язаними до ноги, і переможно кричачи, що ви майже досягли цього, хоч ви спасалися після першої милі. а значить, це обов'язково лише частково звучно і неповно. Це означає, що програми все ще можуть піти не так через властивості, які не відстежуються засобом перевірки типу, і що є програми, які, хоча вони не можуть помилитися, не можуть бути перевірені типом. Імпульс статичного типізації менш частковим і більш повним викликає типові системи надмірно складні та екзотичні, про що свідчать такі поняття, як "фантомні типи" [11] та "типові типи" [10]. Це схоже на спробу пробігти марафон із м’ячем і ланцюжком, прив’язаними до ноги, і переможно кричачи, що ви майже досягли цього, хоч ви спасалися після першої милі. і що існують програми, які, хоча вони не можуть помилитися, не можуть бути перевірені типом. Імпульс статичної типізації менш частковим і більш повним викликає типові системи надмірно складні та екзотичні, про що свідчать такі поняття, як "фантомні типи" [11] та "типові типи" [10]. Це схоже на спробу пробігти марафон із м’ячем і ланцюжком, прив’язаними до ноги, і переможно кричачи, що ви майже досягли цього, хоч ви спасалися після першої милі. і що існують програми, які, хоча вони не можуть помилитися, не можуть бути перевірені типом. Імпульс статичного типізації менш частковим і більш повним викликає типові системи надмірно складні та екзотичні, про що свідчать такі поняття, як "фантомні типи" [11] та "типові типи" [10]. Це схоже на спробу пробігти марафон із м’ячем і ланцюжком, прив’язаними до ноги, і переможно кричачи, що ви майже досягли цього, хоч ви спасалися після першої милі.
Прихильники динамічно набраних мов стверджують, що статичне введення тексту є занадто жорстким і м'якість динамічних мов робить їх ідеально підходящими для систем прототипування із змінами або невідомими вимогами, або що взаємодіють з іншими системами, які змінюються непередбачувано (інтеграція даних та додатків). Звичайно, динамічно набрані мови незамінні для боротьби з по-справжньому динамічною поведінкою програми, такою як перехоплення методів, динамічне завантаження, мобільний код, відображення часу виконання тощо. Джон Остертерхаут стверджує, що статично типізовані системи Мови програмування роблять код менш багаторазовим, більш дослідним, не більш безпечним і менш виразним, ніж динамічно набрані сценарії. Цей аргумент досліджується буквально багатьма прихильниками динамічно набраних мов сценаріїв. Ми стверджуємо, що це помилка і підпадає під ту саму категорію, що і стверджує, що суть декларативного програмування полягає у усуненні присвоєння. Або, як каже Джон Х'юз [8], це логічна неможливість зробити мову більш потужною, опустивши функції. Захищаючи той факт, що затягувати перевірку типу до виконання часу - це добре, грає тактику страуса з тим фактом, що помилки слід вловлювати якомога раніше в процесі розробки. логічно неможливо зробити мову більш потужною, опустивши функції. Захищаючи той факт, що затягувати перевірку типу до виконання часу - це добре, грає тактику страуса з тим фактом, що помилки слід вловлювати якомога раніше в процесі розробки. логічно неможливо зробити мову більш потужною, опустивши функції. Захищаючи той факт, що затягувати перевірку типу до виконання часу - це добре, грає тактику страуса з тим фактом, що помилки слід вловлювати якомога раніше в процесі розробки.
Системи статичного типу прагнуть статично усунути певні помилки, перевіряючи програму, не запускаючи її та намагаючись довести достовірність у певних аспектах. Деякі системи можуть вловлювати більше помилок, ніж інші. Наприклад, C # може усунути нульові винятки вказівника при правильному використанні, тоді як Java не має такої потужності. Twelf має типову систему, яка фактично гарантує, що докази припиняться , "вирішуючи" проблему зупинки .
Однак жодна система типів не є ідеальною. Для усунення певного класу помилок вони також повинні відхиляти певні ідеально дійсні програми, що порушують правила. Ось чому Twelf насправді не вирішує проблему зупинки, вона просто уникає її, викидаючи велику кількість ідеально вагомих доказів, які, як правило, закінчуються дивними способами. Так само система типу Java відкидає PersistentVector
реалізацію Clojure через використання різнорідних масивів. Він працює під час виконання, але система типу не може його перевірити.
З цієї причини більшість типів систем забезпечують "втечі", способи перекриття статичної перевірки. Для більшості мов вони мають форму кастингу, хоча деякі (наприклад, C # і Haskell) мають цілі режими, які позначені як "небезпечні".
Суб'єктивно мені подобається статичне введення тексту. Система статичного типу, реалізована належним чином (підказка: не Java), може стати величезною підмогою у усуненні помилок до того, як вони вийдуть з ладу виробничої системи. Динамічно набрані мови, як правило, вимагають більше тестування одиниць, що в кращі часи нудно. Крім того, статично типізовані мови можуть мати певні функції, які неможливі або небезпечні в системах динамічного типу ( неявні перетворення виникають на увазі). Це все питання вимог та суб'єктивного смаку. Я б більше не будував наступний Eclipse в Ruby, ніж намагався написати резервний скрипт в Асамблеї або виправити ядро за допомогою Java.
О, а люди, які кажуть, що « x набір тексту в 10 разів більш продуктивний, ніж y введення», просто димують димом. Динамічне введення тексту може «відчути» швидше в багатьох випадках, але воно втрачає позицію, коли ви насправді спробуєте змусити запустити свою фантазійну програму . Аналогічно, статичне введення тексту може здатися ідеальною мережею безпеки, але один погляд на деякі більш складні визначення загального типу на Java посилає більшість розробників, які намагаються прослідкувати очі. Навіть при типових системах і продуктивності немає срібної кулі.
Підсумкове зауваження: не турбуйтеся про продуктивність, порівнюючи статичну та динамічну введення тексту. Сучасні JIT, такі як V8 та TraceMonkey, наближаються до статичної мови. Крім того, той факт, що Java насправді поєднує динамічну проміжну мову, повинен бути натяком на те, що для більшості випадків динамічне введення тексту не є величезним вбивцею продуктивності, яке деякі люди роблять.
dadd
оскільки він заздалегідь знає, що операнди є double
s.
Ну, обидва дуже, дуже-дуже неправильно зрозуміли, а також дві абсолютно різні речі. які не є взаємовиключними .
Статичні типи - це обмеження граматики мови. Статично набрані мовні строги можна сказати, що вони не є контекстними. Проста правда полягає в тому, що незручно висловлювати мову порядно в контексті вільних граматик, які не розглядають усі її дані просто як бітові вектори. Системи статичного типу є частиною граматики мови, якщо такі є, вони просто обмежують її більше, ніж могла б граматика, вільна від контексту, граматичні перевірки, таким чином, відбуваються за два проходи над джерелом. Статичні типи відповідають математичному поняттю теорії типів, теорія типів у математиці просто обмежує законність деяких виразів. Мовляв, я не можу сказати 3 + [4,7]
з математики, це через теорію типу.
Статичні типи, таким чином, не є способом «запобігти помилкам» з теоретичної точки зору, вони є обмеженням граматики. Дійсно, за умови, що +, 3 та інтервали мають звичайні теоретичні визначення множини, якщо ми видалимо тип системи, 3 + [4,7]
має досить чітко визначений результат - це набір. "Помилки типу виконання" теоретично не існує, практичне використання системи типу є для запобігання операцій, які для людини не мали б сенсу. Операції - це все-таки лише зміщення та маніпулювання бітами, звичайно.
Суть у цьому полягає в тому, що система типу не може вирішити, чи відбуватимуться такі операції чи ні, чи буде дозволено запускати. Як і в, точно розділіть набір усіх можливих програм у тих, у яких буде помилка "типу", і в тих, які ні. Він може робити лише дві речі:
1: доведіть, що помилки типу трапляться в програмі
2: доведіть, що вони не відбудуться в програмі
Це може здатися, що я суперечу собі. Але те, що перевіряє тип C або Java - це те, що він відхиляє програму як "неграматичну", або як вона називає її "помилка типу", якщо вона не може досягти успіху в 2. Не може довести, що вони не відбудуться, це не означає, що вони не відбудуться, це просто означає, що він не може цього довести. Можливо, програма, яка не матиме помилки типу, буде відхилена просто тому, що компілятор її не може довести. Простий приклад буттяif(1) a = 3; else a = "string";
Звичайно, оскільки це завжди вірно, інакше розгалуження ніколи не буде виконуватися в програмі, і помилка типу не виникає. Але це не може довести ці випадки загальним способом, тому його відкидають. Це головна слабкість багатьох мов, що знаходяться на статичній основі, захищаючи вас від себе, ви обов'язково також захищені у випадках, коли це не потрібно.
Але, всупереч поширеній думці, існують також статично типізовані мови, які працюють за принципом 1. Вони просто відкидають усі програми, які можуть довести, що вони спричинить помилку типу, і передають усі програми, які вони не можуть. Тож можливо, вони дозволяють програмам, у яких є помилки типу, хорошим прикладом є типізована ракетка, це гібрид між динамічним та статичним набором тексту. І дехто може стверджувати, що ви отримуєте найкраще з обох світів у цій системі.
Ще одна перевага статичного введення тексту полягає в тому, що типи відомі під час компіляції, і таким чином компілятор може використовувати це. Якщо ми в Java робимо "string" + "string"
або 3 + 3
обидва +
лексеми в тексті в кінцевому підсумку представляють зовсім іншу операцію і дату, компілятор знає, яку вибрати з типів.
Зараз я хочу зробити тут дуже суперечливе твердження, але маю на увазі: "динамічного набору тексту" не існує .
Звучить дуже суперечливо, але це правда, динамічно набрані мови з теоретичної точки зору нетипізовані . Вони просто статично набрані мови лише з одним типом. Або, простіше кажучи, це мови, які насправді граматично породжуються контекстною вільною граматикою на практиці.
Чому вони не мають типів? Оскільки кожна операція визначена та дозволена для кожного оператора, що таке «помилка типу виконання»? Це з теоретичного прикладу суто побічний ефект . Якщо робити те, print("string")
що друкує рядок - це операція, то так length(3)
, перший має побічний ефект запису string
до стандартного виводу, другий просто error: function 'length' expects array as argument.
, саме так. З теоретичної точки зору не існує такого поняття, як динамічно набрана мова. Вони нетипові
Гаразд, очевидною перевагою "динамічно набраної" мови є експресивна сила, типова система - це не що інше, як обмеження експресивної сили. І взагалі, мови з типовою системою справді мали б певний результат для всіх тих операцій, які не дозволені, якщо типову систему просто ігнорували, результати просто не мали б сенсу для людей. Багато мов втрачають повноту Тюрінга після застосування типової системи.
Очевидним недоліком є той факт, що можуть відбуватися операції, які дають результати, нечутливі для людини. Щоб запобігти цьому, мови, що динамічно набираються, зазвичай переробляють ці операції, а не створюють цей безглуздий результат, вони переосмислюють його, щоб мати побічний ефект виписання помилки та, можливо, повністю зупинити програму. Це зовсім не «помилка», насправді специфікація мови, як правило, передбачає це, це стільки поведінки мови, скільки друку рядка з теоретичної точки зору. Таким чином, системи типу змушують програміста міркувати про потік коду, щоб переконатися, що цього не відбувається. Або в самому справі, причина , так що вона робитьщо може також бути корисним у деяких пунктах для налагодження, показуючи, що це зовсім не «помилка», а чітко визначена властивість мови. Фактично, єдиний залишок "динамічного набору тексту", який має більшість мов, захищає від поділу на нуль. Ось що таке динамічне введення тексту, немає типів, немає більше типів, ніж нуль - це інший тип, ніж усі інші числа. Те, що люди називають "типом", - це лише інша властивість даної, наприклад, довжини масиву або першого символу рядка. І багато динамічно набраних мов також дозволяють виписати такі речі "error: the first character of this string should be a 'z'"
.
Інша справа, що мови, що динамічно набираються, мають тип, доступний під час виконання, і зазвичай вони можуть перевіряти його, мати справу з ним і вирішувати з нього. Звичайно, теоретично це не інакше, ніж отримати доступ до першого символу масиву і побачити, що це таке. Насправді, ви можете створити свій власний динамічний C, просто використовуйте лише один тип, наприклад довгий довгий int, і використовуйте перші 8 біт його для зберігання свого типу і записуйте відповідно функції, які перевіряють його та виконують додавання з плаваючою чи цілою чисельністю. У вас є статично набрана мова одного типу або динамічна мова.
На практиці це все показує, що статично типові мови зазвичай використовуються в контексті написання комерційного програмного забезпечення, тоді як динамічно набрані мови, як правило, використовуються в контексті вирішення деяких проблем і автоматизації деяких завдань. Написання коду статично набраними мовами просто займає багато часу і громіздке, тому що ви не можете робити те, що ви знаєте, вийде нормально, але система типу все одно захищає вас від себе від помилок, які ви не робите. Багато кодерів навіть не усвідомлюють, що вони роблять це, бо це в їхній системі, але коли ви кодуєте статичні мови, ви часто обмінюєтесь тим, що система типу не дозволить вам робити речі, які не можуть піти не так, тому що це не можу довести, що не піде не так.
Як я зазначав, "статично набраний" в цілому означає випадок 2, винний, поки не доведений невинний. Але деякі мови, які взагалі не виводять свою систему типу з теорії типів, використовують правило 1: Інокентій до тих пір, поки не буде доведено вину, що може бути ідеальним гібридом. Тож, можливо, набрана ракетка саме для вас.
Крім того, для більш абсурдного і крайнього прикладу, я зараз реалізую мову, де "типи" справді є першим символом масиву, це дані, дані "типу", "типу", що є самим собою тип і дата, єдина дата, яка є самою типом. Типи не є обмеженими або обмеженими статично, але нові типи можуть створюватися на основі інформації про час виконання.
Мабуть, найбільшою «перевагою» динамічного набору тексту є менша крива навчання. Не існує системи типів для вивчення та нетривіального синтаксису для кутових випадків, таких як обмеження типу. Це робить динамічне введення тексту доступним для набагато більшої кількості людей та можливо для багатьох людей, для яких складні системи статичного типу недоступні. Отже, динамічне набору тексту набуло контекстів освіти (наприклад, схема / Python на MIT) та мов, що стосуються домену для непрограмістів (наприклад, Mathematica ). Динамічні мови також зачепилися в ніші, де у них мало конкуренції або взагалі немає (наприклад, Javascript).
Найбільш стислі динамічно набрані мови (наприклад, Perl, APL, J, K, Mathematica ) є доменними і можуть бути значно більш короткими, ніж найбільш стислі статичні типи мов загального призначення (наприклад, OCaml ) у нішах, для яких вони були розроблені. .
Основними недоліками динамічного набору тексту є:
Помилки типу виконання.
Домогтися того ж рівня коректності може бути дуже важко або навіть практично неможливо і вимагає значно більше тестування.
Немає підтвердженої компілятором документації.
Низька продуктивність (як правило, під час виконання, але іноді на час компіляції, наприклад, схема Сталіна) та непередбачувана продуктивність через залежність від складних оптимізацій.
Особисто я виріс на динамічних мовах, але не торкнувся їх 40-дюймовим полюсом, як професіонал, якщо б не було інших життєздатних варіантів.
З статті Artima's Typing: Strong vs. слабкі, статичні та динамічні статті:
сильне введення тексту запобігає операціям перемішування між невідповідними типами. Для змішування типів потрібно використовувати явну конверсію
слабке введення означає, що ви можете змішувати типи без явного перетворення
У статті Паскаля Костанца « Динамічне проти статичного введення тексту - аналіз на основі шаблону» (PDF) він стверджує, що в деяких випадках статичне введення є більш схильним до помилок, ніж динамічним введенням тексту. Деякі мови, набрані статичним способом, змушують вас вручну імітувати динамічне введення тексту, щоб зробити "Правильну річ". Це обговорюється в Lambda the Ultimate .
Це залежить від контексту. Є багато переваг, які підходять як для динамічної набраної системи, так і для сильної набраної. Я думаю, що потік мови динамічних типів відбувається швидше. Динамічні мови не обмежуються атрибутами класу та компілятором, що мислить, що відбувається в коді. У вас є якась свобода. Крім того, динамічна мова зазвичай є більш виразною і призводить до меншої кількості коду, що добре. Незважаючи на це, це більше схильність до помилок, що також сумнівно і більше залежить від покриття тесту одиниці. Простий прототип з динамічним язиком, але технічне обслуговування може стати кошмаром.
Основний приріст над статичною системою набору - це підтримка IDE і, безумовно, статичний аналізатор коду. Ви стаєте впевненішим у коді після кожної зміни коду. Зміст - це спокій торта з такими інструментами.
Про статичні та динамічні мови існує багато різних речей. Для мене головна відмінність полягає в тому, що в динамічних мовах змінні не мають фіксованих типів; натомість типи прив’язуються до значень. Через це точний код, який виконується, не визначається до часу виконання.
У ранніх або наївних реалізаціях це величезне зниження продуктивності, але сучасні JIT наближаються до найкращого, що можна отримати, оптимізуючи статичні компілятори. (у деяких випадках із бахромою, навіть краще, ніж це).
Це все про правильний інструмент для роботи. Ні краще, ні 100% часу. Обидві системи були створені людиною і мають вади. Вибачте, але ми смокчемо і робимо ідеальні речі.
Мені подобається динамічне введення тексту, оскільки воно виходить з мого шляху, але так, помилки під час виконання можуть повзати, що я не планував. Де статичне введення тексту може виправити вищезгадані помилки, але загнати початківця (набраними мовами) програміст божевільно намагається перекидати між постійною символом та рядком.
Статичне введення тексту: такі мови, як Java та Scala, набираються статично.
Змінні повинні бути визначені та ініціалізовані до їх використання в коді.
для екс. int x; х = 10;
System.out.println (x);
Динамічне введення тексту: Perl - це динамічна набрана мова.
Змінні не потрібно ініціалізувати до їх використання в коді.
у = 10; використовувати цю змінну в пізнішій частині коду