Языки динамического типа и языки статического типа - PullRequest
201 голосов
/ 24 сентября 2008

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

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

Ответы [ 9 ]

137 голосов
/ 24 сентября 2008

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

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

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

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

118 голосов
/ 24 сентября 2008

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

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

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

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

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

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

44 голосов
/ 06 июля 2010

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

Статические типы являются ограничением грамматики языка. Строго типизированные языки строго можно сказать, что они не являются контекстно-свободными. Простая истина в том, что становится неразумно выражать язык разумно в контекстно-свободных грамматиках, которые не обрабатывают все свои данные просто как битовые векторы. Системы статических типов являются частью грамматики языка, если таковые имеются, они просто ограничивают ее больше, чем могла бы сделать контекстно-свободная грамматика, поэтому грамматические проверки происходят в два прохода над источником. Статические типы соответствуют математическому понятию теории типов, теория типов в математике просто ограничивает законность некоторых выражений. Мол, я не могу сказать 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, то оба + токена в тексте в конце представляют совершенно разные операции и данные, и компилятор знает, какой из этих типов выбрать один.

Теперь я собираюсь сделать очень спорное утверждение здесь, но иметь со мной: «динамическая типизация» не существует 1032 *.

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

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

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

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

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

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

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

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

24 голосов
/ 19 апреля 2010

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

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

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

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

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

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

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

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

11 голосов
/ 24 сентября 2008

Из Artima's Печатание: Сильный против слабого, Статический против динамического Статья:

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

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

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

2 голосов
/ 01 декабря 2009

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

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

0 голосов
/ 27 июня 2013

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

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

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

System.out.println (х);

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

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

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

0 голосов
/ 24 сентября 2008

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

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

0 голосов
/ 24 сентября 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...