Проблемы динамической типизации в сравнении

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

Строгая типизация в головах программистов на Java или C# это нечто незыблемое. В разговоре с ними создается ощущение, что она на уровне восприятия ощущается как земля под ногами. Убери строгую типизацию и все утонут в хаосе и неразберихе.

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

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

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

Что такое типизация в языках программирования и при чем здесь компилятор

Говоря о различиях к подходу в определении типов в языках программирования, стоит учитывать, что динамическая типизация присуща в основном языкам интерпретируемым. В то время как строгая, свойственна компилируемым языкам.

Строгая типизация — это своего рода способ преждевременной оптимизации. Программист, пытается заранее решать проблемы теряя возможность изменять тип данных «на лету». Избыточный максимализм в случае с компилируемыми программами, объясняется ценой ошибки.

И цена бывает высока. Бывает очень высока. Особенно если ошибок много. Конечный пользователь получает продукт, который в процессе работы выдает фатальные ошибки, пишет в поддержку приложения. Служба поддержки передает обращения в отдел разработки ПО. Проходит время, программисты исправляют баги и предлагают пользователю обновить программу. Покупатель может потребовать деньги назад, что влечет финансовые потери для разработчиков. Исправить бинарные файлы скомпилированного приложения самостоятельно, пользователь само-собой не в состоянии.

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

Цена ошибки снижается, ели вы предоставляете конечному пользователю исходный код своей программы. Часто, пользователи в состоянии сами поправить ошибки, а затем прислать разработчикам свой вариант решения проблемы. Даже если конечный пользователь совсем не сведущ в программировании, всегда есть вариант нанять студента на бирже фриланса, который за 15 минут и пирожок, вернет программе работоспособность.

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

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

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

 

Реальные преимущества динамической типизации

  1. Простота создания универсальных коллекций.
  2. Легкость написания. Не нужно заморачиваться какие данные могут присутствовать в объекте или массиве, просто пользуемся ими.
  3. Низкий порог вхождения.

Реальные преимущества строгой (статической) типизации

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

Вот сводная табличка с Хабра, которая демонстрирует разницу в типизации различных языков, я немного расширил ее:

Язык Статический? Неявные преобразования? Строгие правила? Безопасный для памяти?
C Сильный Когда как Слабый Слабый
C# Сильный Когда как Сильный Сильный
Java Сильный Когда как Сильный Сильный
Haskell Сильный Сильный Сильный Сильный
Python Слабый Когда как Слабый Сильный
PHP Слабый Когда как Слабый Сильный
JavaScript Слабый Слабый Слабый Сильный

(«Когда как» в колонке «Неявные преобразования» означает, что разделение между сильным и слабым зависит от того, какие преобразования мы считаем приемлемыми).

_________________________

НЕ В ТЕМУ: Ради этой статьи мне пришлось на время отложить статью о построении локального окружения на Docker. В ближайшие дни я выложу готовый текст, как оказалось, тема немного сложнее. Даже у меня, с моим относительно небольшим количеством проектов, требования к окружению могут различаться в зависимости от проекта. Так что статья потребовала дополнительного анализа.

StackUP