Языки динамических типов в сравнении с языками статических типов

StackOverflow https://stackoverflow.com/questions/125367

Вопрос

Каковы преимущества и ограничения языков динамического типа по сравнению с языками статического типа?

Смотрите также: что это за любовь к динамичным языкам (гораздо более аргументированная тема ...)

Это было полезно?

Решение

Способность интерпретатора определять тип и преобразования типов ускоряет время разработки, но это также может спровоцировать сбои во время выполнения, которые вы просто не можете получить в статически типизированном языке, где вы обнаруживаете их во время компиляции.Но какой из них лучше (или даже всегда ли это так) горячо обсуждается в сообществе в наши дни (и уже давно).

Хороший взгляд на этот вопрос взят из Статический ввод Текста, где это возможно, Динамический ввод текста, когда это необходимо:Конец холодной войны между Языками программирования авторы : Эрик Мейер и Питер Дрейтон из Microsoft:

Сторонники статической типизации утверждают, что преимущества статической типизации включают более раннее обнаружение ошибок программирования (напримерпредотвращение добавления целого числа к логическому значению), лучшая документация в виде подписей типов (напримервключение количества и типов аргументов при разрешении имен), больше возможностей для оптимизации компилятора (напримерзамена виртуальных вызовов прямыми вызовы, когда точный тип получателя известен статически), повышение эффективности выполнения (напримерне все значения должны иметь динамический тип) и лучшее время разработки опыт разработчика (напримерзная тип приемника, IDE может представить выпадающее меню со всеми применимыми элементами).Статическая типизация Фанатики пытаются заставить нас поверить, что “хорошо типизированные программы не могут пойти не так”.Хотя это, безусловно, звучит впечатляюще, это довольно бессмысленное утверждение.Статическая проверка типов - это абстракция во время компиляции поведения вашей программы во время выполнения, и следовательно, она обязательно является лишь частично надежной и неполной.Это означает, что программы все еще могут работать неправильно из-за свойств, которые не отслеживаются средством проверки типов, и что существуют программы, которые, хотя и не могут работать неправильно, не могут быть проверены на тип. Стремление сделать статическую типизацию менее частичной и более полной приводит к тому, что системы типов становятся чрезмерно сложными и экзотическими, о чем свидетельствуют такие концепции , как “фантомные типы” [11] и “шаткие типы” [10].Это все равно что пытаться пробежать марафон с мячом и цепью, привязанной к ноге, и торжествующе кричать, что ты почти добрался, несмотря на то, что выпрыгнул после первой мили.

Сторонники динамически типизированных языков утверждают, что статическая типизация слишком жесткая, и что мягкость динамических языков делает их идеально подходящими для создания прототипов систем с изменяющимися или неизвестными требованиями, или которые взаимодействуют с другими системами которые непредсказуемо меняются (интеграция данных и приложений).Конечно, динамически типизированные языки незаменимы для работы с действительно динамическим поведением программы, таким как перехват методов, динамическая загрузка, мобильный код, отражение во время выполнения и т.д.В первой из всех статей по сценариям [16] Джон Оустерхаут утверждает что статически типизированные системы языки программирования делают код менее многоразовым, более подробным, не более безопасным и менее выразительным, чем динамически типизированные языки сценариев.Этот аргумент буквально повторяется многими сторонниками динамически типизированных скриптовых языков.Мы утверждаем, что это логическая ошибка и подпадает под ту же категорию, что и утверждение о том, что суть декларативного программирования заключается в устранении присваивания.Или, как говорит Джон Хьюз [8], логично, что невозможно сделать язык более мощным, опуская функции.Защищая то, что затягивает все проверка типа времени выполнения, является хорошим вещь, играет тактика страуса с тот факт, что ошибки должны быть пойманным на начальных этапах развития возможно.

Другие советы

Системы статического типа стремятся статически устранить определенные ошибки, проверяя программу без ее запуска и пытаясь доказать надежность в определенных отношениях.Системы некоторых типов способны улавливать больше ошибок, чем другие.Например, C # может устранять исключения с нулевым указателем при правильном использовании, в то время как Java не обладает такой способностью.У Twelf есть система типов, которая на самом деле гарантирует, что проверка будет прекращена, "решая" проблему проблема остановки.

Однако ни одна система типов не является совершенной.Чтобы устранить определенный класс ошибок, они также должны отклонить определенные абсолютно допустимые программы, которые нарушают правила.Вот почему Twelf на самом деле не решает проблему остановки, он просто избегает ее, выбрасывая большое количество совершенно достоверных доказательств, которые заканчиваются странным образом.Аналогично, система типов Java отвергает Clojure PersistentVector реализация обусловлена использованием разнородных массивов.Это работает во время выполнения, но система типов не может это проверить.

По этой причине большинство систем типов предоставляют "экранирования", способы переопределения статической проверки.Для большинства языков они принимают форму приведения, хотя некоторые (например, C # и Haskell) имеют целые режимы, которые помечены как "небезопасные".

Субъективно, мне нравится статическая типизация.Реализовано правильно (подсказка: нет Java), система статических типов может оказать огромную помощь в устранении ошибок до того, как они приведут к сбою производственной системы.Динамически типизированные языки, как правило, требуют большего количества модульного тестирования, что и в лучшие времена утомительно.Кроме того, статически типизированные языки могут обладать определенными функциями, которые либо невозможны, либо небезопасны в системах динамических типов (неявные преобразования приходит на ум).Все это вопрос требований и субъективного вкуса.Я бы не стал создавать следующий Eclipse на Ruby, как не стал бы пытаться написать сценарий резервного копирования на ассемблере или исправлять ядро с помощью Java.

О, и люди, которые так говорят ".x набор текста в 10 раз производительнее, чем y набрав текст", вы просто пускаете дым.Динамический ввод текста во многих случаях может "ощущаться" быстрее, но он теряет свои позиции, как только вы действительно пытаетесь создать свое необычное приложение бежать.Аналогично, статическая типизация может показаться идеальной страховочной сеткой, но один взгляд на некоторые из более сложных определений универсальных типов в Java заставляет большинство разработчиков поспешно закрывать глаза.Даже при наличии типовых систем и производительности нет "серебряной пули".

Заключительная нота:не беспокойтесь о производительности при сравнении статической и динамической типизации.Современные JITS, такие как V8 и TraceMonkey, опасно близки к статической производительности языка.Кроме того, тот факт, что Java на самом деле компилируется до динамического промежуточного языка по своей сути, должен быть намеком на то, что в большинстве случаев динамическая типизация не является огромным убийцей производительности, как считают некоторые люди.

Что ж, и то, и другое очень, очень, очень неправильно понято, а также это две совершенно разные вещи. это не взаимоисключающие понятия.

Статические типы - это ограничение грамматики языка.Строго говоря, можно сказать, что статически типизированные языки не являются контекстно-свободными.Простая истина заключается в том, что становится неудобно разумно выражать язык в контекстно-свободных грамматиках, которые не обрабатывают все его данные просто как битовые векторы.Системы статических типов являются частью грамматики языка, если таковые имеются, они просто ограничивают ее больше, чем могла бы контекстно-свободная грамматика, таким образом, грамматические проверки действительно происходят в два прохода по исходному тексту.Статические типы соответствуют математическому понятию теории типов, теория типов в математике просто ограничивает допустимость некоторых выражений.Например, я не могу сказать 3 + [4,7] в математике это происходит из-за теории типов.

Таким образом, статические типы - это не способ "предотвратить ошибки" с теоретической точки зрения, это ограничение грамматики.Действительно, при условии, что +, 3 и интервалы имеют обычные установленные теоретические определения, если мы уберем систему типов 3 + [4,7]имеет довольно четко определенный результат, который является набором.Теоретически "ошибок типа во время выполнения" не существует, практическое использование системы типов заключается в предотвращении операций, которые для людей это не имело бы никакого смысла.Конечно, операции по-прежнему представляют собой всего лишь сдвиг и манипулирование битами.

Загвоздка в том, что система типов не может решить, будут ли выполняться такие операции или нет, если ей будет разрешено выполняться.Например, точно разделите набор всех возможных программ на те, у которых будет "ошибка типа", и те, у которых ее нет.Он может делать только две вещи:

1:докажите, что в программе будут возникать ошибки типа
2:докажите, что они не будут встречаться в программе

Может показаться, что я противоречу сам себе.Но что делает программа проверки типов C или Java, так это отклоняет программу как "неграмматичную", или, как она называет это, "ошибку типа", если она не могу добейтесь успеха на уровне 2.Он не может доказать, что они не произойдут, это не значит, что они не произойдут, это просто означает, что он не может этого доказать.Вполне может оказаться, что программа, у которой не будет ошибки типа, будет отклонена просто потому, что это не может быть доказано компилятором.Простым примером является if(1) a = 3; else a = "string";, конечно, поскольку это всегда верно, ветвь else никогда не будет выполнена в программе, и ошибка типа не возникнет.Но он не может доказать эти случаи в общем виде, поэтому он отклонен.Это основная слабость многих статически типизированных языков: защищая вас от самих себя, вы обязательно защищены и в тех случаях, когда вам это не нужно.

Но, вопреки распространенному мнению, существуют также статически типизированные языки, которые работают по принципу 1.Они просто отклоняют все программы, в отношении которых они могут доказать, что это вызовет ошибку типа, и пропускают все программы, в отношении которых они не могут.Таким образом, возможно, что они допускают программы, в которых есть ошибки ввода, хорошим примером является Typed Racket, это гибрид динамической и статической типизации.И кто-то может возразить, что в этой системе вы получаете лучшее из обоих миров.

Еще одним преимуществом статической типизации является то, что типы известны во время компиляции, и, таким образом, компилятор может использовать это.Если мы в Java делаем "string" + "string" или 3 + 3, оба + токены в тексте в конечном итоге представляют собой совершенно другую операцию и данные, компилятор знает, какой выбрать из типов в одиночку.

Теперь я собираюсь сделать здесь очень противоречивое заявление, но потерпите меня: "динамическая типизация" не существует.

Звучит очень спорно, но это правда, динамически типизированные языки - это с теоретической точки зрения нетипизированный.Это просто статически типизированные языки только с одним типом.Или, проще говоря, это языки, которые на практике действительно грамматически порождаются контекстно-свободной грамматикой.

Почему у них нет типов?Поскольку каждая операция определена и разрешена для каждого операнта, что именно является "ошибкой типа среды выполнения"?Это чисто теоретический пример. побочный эффект.Если делаешь print("string") который печатает строку, является операцией, тогда это тоже length(3), первое имеет побочный эффект написания string к стандартному выводу, последний просто error: function 'length' expects array as argument., - вот и все.С теоретической точки зрения не существует такого понятия, как динамически типизированный язык.Они такие нетипизированный

Итак, очевидным преимуществом "динамически типизированного" языка является выразительная сила, система типов - это не что иное, как ограничение выразительной силы.И в целом, языки с системой типов действительно имели бы определенный результат для всех тех операций, которые не разрешены, если бы система типов была просто проигнорирована, результаты просто не имели бы смысла для людей.Многие языки теряют свою полноту по Тьюрингу после применения системы типов.

Очевидным недостатком является тот факт, что могут происходить операции, которые приведут к результатам, бессмысленным для человека.Чтобы защититься от этого, языки с динамической типизацией обычно переопределяют эти операции, вместо того чтобы выдавать этот бессмысленный результат, они переопределяют его как побочный эффект записи ошибки и, возможно, полной остановки программы.Это вовсе не "ошибка", на самом деле, спецификация языка обычно подразумевает это, это такое же поведение языка, как и печать строки с теоретической точки зрения.Таким образом, системы типов вынуждают программиста рассуждать о потоке кода, чтобы убедиться, что этого не произойдет.Или, действительно, рассуждать так, чтобы это делает happen также может быть полезен в некоторых моментах для отладки, показывая, что это вовсе не "ошибка", а четко определенное свойство языка.По сути, единственный остаток "динамической типизации", который есть в большинстве языков, - это защита от деления на ноль.Это и есть динамическая типизация, здесь нет типов, их не больше, чем ноль - это другой тип, чем все остальные числа.То, что люди называют "типом", - это просто еще одно свойство базы данных, такое как длина массива или первый символ строки.И многие языки с динамической типизацией также позволяют вам записывать такие вещи, как "error: the first character of this string should be a 'z'".

Другое дело, что динамически типизированные языки имеют тип, доступный во время выполнения, и обычно могут проверять его, работать с ним и принимать решения на его основе.Конечно, теоретически это ничем не отличается от доступа к первому символу массива и просмотра того, что это такое.Фактически, вы можете создать свой собственный динамический C, просто используйте только один тип, такой как long long int, и используйте первые 8 его битов для сохранения вашего "типа" и записи соответствующих функций, которые проверяют его и выполняют сложение с плавающей точкой или целым числом.У вас есть статически типизированный язык с одним типом или динамический язык.

На практике все это показывает, что статически типизированные языки обычно используются в контексте написания коммерческого программного обеспечения, тогда как динамически типизированные языки, как правило, используются в контексте решения некоторых проблем и автоматизации некоторых задач.Написание кода на статически типизированных языках просто занимает много времени и является громоздким, потому что вы не можете делать то, что, как вы знаете, получится хорошо, но система типов по-прежнему защищает вас от самих себя за ошибки, которые вы не совершаете.Многие программисты даже не осознают, что они делают это, потому что это заложено в их систему, но когда вы кодируете на статических языках, вы часто обходите тот факт, что система типов не позволит вам делать то, что не может пойти не так, потому что она не может доказать, что это не пойдет не так.

Как я уже отмечал, "статически типизированный" в общем случае означает случай 2: виновен, пока не доказана невиновность.Но некоторые языки, которые вообще не выводят свою систему типов из теории типов, используют правило 1:Невиновен до тех пор, пока вина не будет доказана, что могло бы стать идеальным гибридом.Так что, возможно, эта ракетка для вас.

Кроме того, ну, для более абсурдного и экстремального примера, в настоящее время я реализую язык, где "типы" действительно являются первым символом массива, это данные, данные "типа", "type", которые сами по себе являются типом и datum, единственным datum, который имеет себя в качестве типа.Типы не являются конечными или ограниченными статически, но новые типы могут быть сгенерированы на основе информации о времени выполнения.

Возможно, самым большим "преимуществом" динамической типизации является меньшая кривая обучения.Не существует системы типов для изучения и нет нетривиального синтаксиса для угловых случаев, таких как ограничения типов.Это делает динамический ввод доступным для гораздо большего числа людей и выполнимым для многих людей, для которых сложные системы статического ввода недоступны.Следовательно, динамическая типизация получила широкое распространение в контексте образования (например,Scheme /Python в MIT) и предметно-ориентированные языки для непрограммистов (например Математика).Динамические языки также завоевали популярность в нишах, где у них практически нет конкуренции (например,Javascript).

Наиболее краткие языки с динамической типизацией (напримерPerl, APL, J, K, Математика) зависят от предметной области и могут быть значительно более краткими, чем наиболее краткие статически типизированные языки общего назначения (например OCaml) в нишах, для которых они были предназначены.

Основными недостатками динамической типизации являются:

  • Ошибки типа во время выполнения.

  • Достичь такого же уровня корректности может быть очень сложно или даже практически невозможно, и для этого требуется значительно больше тестирования.

  • Нет документации, проверенной компилятором.

  • Низкая производительность (обычно во время выполнения, но иногда и во время компиляции, напримерСхема Сталина) и непредсказуемая производительность из-за зависимости от сложных оптимизаций.

Лично я вырос на динамических языках, но как профессионал не стал бы прикасаться к ним с 40-футовым стажем, если бы не было других приемлемых вариантов.

От Артимы Ввод текста:Сильный противСлабый, Статичный по сравнению сДинамичный Статья:

строгая типизация предотвращает смешивание операций между несовпадающими типами.Чтобы смешивать типы, вы должны использовать явное преобразование

слабая типизация означает, что вы можете смешивать типы без явного преобразования

В статье Паскаля Костанцы, Динамический противСтатическая типизация — Анализ на основе шаблонов (PDF), он утверждает, что в некоторых случаях статический ввод текста более подвержен ошибкам, чем динамический.Некоторые языки со статической типизацией вынуждают вас вручную эмулировать динамическую типизацию, чтобы делать "Правильные вещи".Это обсуждается на Лямбда-предельный.

Это зависит от контекста.Существует множество преимуществ, которые подходят как для динамической типизированной системы, так и для строго типизированной.Я придерживаюсь мнения, что поток языка динамических типов происходит быстрее.Динамические языки не ограничены атрибутами класса и представлением компилятора о том, что происходит в коде.У тебя есть своего рода свобода.Кроме того, динамический язык обычно более выразителен и приводит к меньшему количеству кода, что хорошо.Несмотря на это, он более подвержен ошибкам, что также сомнительно и в большей степени зависит от покрытия модульным тестированием.Это простой прототип с dynamic lang, но техническое обслуживание может превратиться в кошмар.

Основным преимуществом по сравнению со статической типизированной системой является поддержка IDE и, конечно же, статический анализатор кода.Вы становитесь более уверенным в коде после каждого изменения кода.С помощью таких инструментов уход за тортом становится проще простого.

В статических и динамических языках есть много разных особенностей.Для меня главное отличие заключается в том, что в динамических языках переменные не имеют фиксированных типов;вместо этого типы привязаны к значениям.Из-за этого точный код, который будет выполняться, не определен до времени выполнения.

В ранних или наивных реализациях это приводит к огромному снижению производительности, но современные JITS дразняще приближаются к лучшему, что вы можете получить с помощью оптимизации статических компиляторов.(в некоторых второстепенных случаях даже лучше, чем это).

Все дело в правильном инструменте для этой работы.Ни то, ни другое не лучше в 100% случаев.Обе системы были созданы человеком и имеют недостатки.Извините, но мы отстой и готовим идеальные вещи.

Мне нравится динамический ввод текста, потому что это не мешает мне, но да, могут возникнуть ошибки во время выполнения, которые я не планировал.Где, поскольку статическая типизация может исправить вышеупомянутые ошибки, но свести с ума начинающего (на типизированных языках) программиста, пытающегося использовать комбинацию между постоянным символом и строкой.

Статическая типизация: Такие языки, как Java и Scala, имеют статическую типизацию.

Переменные должны быть определены и инициализированы, прежде чем они будут использоваться в коде.

напримерint x;x = 10;

System.out.println(x) Система.выход.печать (x);

Динамический ввод текста: Perl - это динамический типизированный язык.

Переменные не нужно инициализировать перед их использованием в коде.

y=10;используйте эту переменную в более поздней части кода

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top