Есть много сильных мнений, окружающих дебаты, но, очевидно, это на самом деле не вопрос мнения, это вопрос фактов . Итак, мы должны смотреть на эмпирические исследования . И доказательства этого очевидны:
Да , статическая типизация стоит компромиссов - и не только немного, но на самом деле существенно . На самом деле, убедительные доказательства показывают, что статическая типизация может уменьшить количество ошибок в коде как минимум на 15% (и это низкая оценка, фактический процент почти наверняка больше). Это потрясающе высокое число: я думаю, что даже большинство сторонников статической типизации не подумали бы, что это имеет столь радикальное значение.
Подумайте об этом: если кто-то сказал вам, что существует простой способ уменьшить количество ошибок в вашем проекте на 15% за ночь, это должно быть просто.1 Это почти всем известная серебряная пуля.
Доказательства представлены в статье Печатать или не печатать: количественное определение обнаруживаемых ошибок в JavaScript » Чжэн Гао, Кристиана Берда и Эрла Т. Барра. Я призываю всех прочитать это, это хорошо написанная статья, которая представляет образцовое исследование.
Трудно кратко резюмировать, насколько строго авторы выполнили свой анализ, но вот (очень грубый) план:
TypeScript и Flow - это два языка программирования, основанные на JavaScript, которые, в остальном совместимые, добавляют подсказки типов и проверку статических типов. Это позволяет дополнять существующий код типами, а затем проверять его тип.
Исследователи собирали проекты с открытым исходным кодом, написанные на JavaScript, из GitHub, просматривали исправленные отчеты об ошибках и пытались свести каждую из сообщенных ошибок к коду, который будет обнаружен статической проверкой типов TypeScript или Flow. Это позволило им оценить нижнюю границу процента ошибок, которые можно исправить с помощью статической типизации.
Исследователи приняли строгие меры предосторожности, чтобы их анализ не рассматривал ошибку, не связанную с типом, как связанную с типами. 2
По сравнению с прошлыми исследованиями это новое исследование имеет особые преимущества:
- Существует прямое сравнение статической и динамической типизации с несколькими (если таковые имеются) смешивающими факторами, поскольку единственное различие между JavaScript и TypeScript / Flow - это типизация.
- Они выполняют репликацию по нескольким измерениям, проверяя и TypeScript, и Flow (т. Е. Системы разных типов), и заставляя разных людей воспроизводить (ручную) аннотацию типа для исправления ошибок. И они выполняют это на большом количестве кодовых баз из разных проектов.
- В статье измеряется прямое влияние статической типизации на исправляемые ошибки (а не на более неопределенное качество).
- Авторы заранее определяют строгую модель того, что и как измерять. Кроме того, их описание невероятно ясно и позволяет легко анализировать недостатки (это всегда хорошо, когда исследовательская работа раскрывает себя атакам: если никакие атаки не могут помешать ее аргументам, она выходит еще сильнее). 3
- Они выполняют надлежащий анализ мощности, чтобы их размер выборки был достаточным, а последующий статистический анализ - герметичным.
- Они чрезмерно консервативны, чтобы исключить смешные объяснения, и измеряют только одну движущуюся часть. Кроме того, они ограничивают свой анализ ошибками, которые могут быть немедленно исправлены путем включения типов, и исключают все, что может потребовать более сложного рефакторинга для обеспечения возможности ввода. Таким образом, на самом деле, эффект, вероятно, намного больше, но, конечно, не меньше, чем они сообщили.
- И, наконец, они не находят незначительного эффекта, но ошеломляют разницу. Несмотря на их чрезмерно консервативную процедуру, даже на нижнем уровне 95% -ного доверительного интервала они обнаруживают, что есть как минимум 10% ошибок, которые просто исчезают при минимальных проверках добавленных типов.
Если в статье нет фундаментального недостатка, который еще никто не обнаружил, статья окончательно демонстрирует большое преимущество статической типизации практически без затрат. 4
С исторической точки зрения, исследования по типизации дисциплин в программировании начались очень быстро, потому что в течение долгого времени доказательства были не совсем ясны. Причина этого в том, что проводить систематические эксперименты, чтобы исследовать эффект статической и динамической типизации, нелегко: систематический эксперимент должен изолировать эффект, который мы исследуем. И, к сожалению, мы не можем изолировать эффект от набора текста, поскольку он привязан к языкам программирования.
На самом деле были языки программирования, которые допускали как статическую, так и динамическую типизацию на разных диалектах (например, VB с Option Strict
On
или Off
, или статически типизированный Лисп). Тем не менее, они не очень подходили для прямого сравнения, что особенно важно, потому что не было существующих, достаточно больших баз кода, позволяющих проводить прямое сравнение. В лучшем случае мы могли бы сравнить их в «лабораторных условиях», где испытуемые случайным образом решают задачу в статически или динамически типизированном варианте языка.
К сожалению, эти задания искусственного программирования плохо моделируют использование в реальных условиях. В частности, многие из них невелики по объему и решают четко определенную проблему, которая может быть обобщена на половине страницы текста.
К счастью, это в прошлом, потому что TypeScript, Flow и JavaScript действительно являются одними и теми же языками, за исключением статической типизации, и потому что существует обширный реальный набор данных кода и ошибок для выборки.
1 Вдохновлен цитатой из оригинальной статьи.
2 Я не совсем доволен этим: одна из основных сильных сторон статически типизированных языков заключается в том, что якобы не связанные с типом проблемы могут быть сформулированы способами, которые могут быть статически проверены. Это преобразует многие логические ошибки в ошибки типов, что резко увеличивает количество ошибок, которые могут быть обнаружены статической типизацией. Фактически, статья грубо классифицирует ошибки, не связанные с типом, и я утверждаю, что большой процент из них может быть фактически обнаружен статической типизацией.
3 Я приглашаю любого, особенно сторонников динамической типизации, попытаться найти нерешенные недостатки в анализе. Я не думаю, что их много (если таковые имеются), и я уверен, что никакой потенциальный недостаток существенно не изменит результат.
4 Я подозреваю, что фактическая стоимость статической типизации в реальных крупномасштабных проектах не существует, поскольку тогда она становится естественной частью архитектуры и может даже упростить планирование. Исправление ошибок статического типа требует времени, но намного меньше, чем ошибки, обнаруженные позже. Это было тщательно изучено эмпирически и известно десятилетиями (см., Например, Code Complete ).