Откровенно говоря, я устал слушать о проблемах PHP от людей, мягко говоря не компетентных в его реальных проблемах. Очень часто, вступая в такой спор я заранее знаю к чему он будет сведен. Отринув все стереотипы, например о том, что PHP не работает с архивами или работает слишком медленно в сравнении с тем же С++, спор сводится к различиям в подходах программирования и типизации.
Строгая типизация в головах программистов на Java или C# это нечто незыблемое. В разговоре с ними создается ощущение, что она на уровне восприятия ощущается как земля под ногами. Убери строгую типизацию и все утонут в хаосе и неразберихе.
Я хочу подчеркнуть, что речь идет в основном про начинающих программистов, так как люди со стажем, скорее всего уже попробовали JavaScript, PHP или Python. Ну или просто интересовались данной темой, так как в любом случае на динамически типизированных языках написано много кода и большая часть этого кода распространяется свободно, в виде исходников. Опытные программисты вообще не склонны говорить плохо о языках программирования. В кругах профессионалов это моветон.
На рассуждения новичка о том, что один язык плох в сравнении с другим, профессионал задаст вопрос, а какую собственно, проблему мы решаем. Печальный факт заключается в том, что новичок может просто не понять о чем его спрашивают.
Далее, я попытаюсь объяснить (в первую очередь для себя, вывести некое упорядоченное обоснование) почему это так и понимая, что ступаю на земли священных войн, убедительно прошу считать все нижеизложенное моим личным мнением. Мое мнение может изменится со временем, так же как меняются и сами языки программирования.
Что такое типизация в языках программирования и при чем здесь компилятор
Говоря о различиях к подходу в определении типов в языках программирования, стоит учитывать, что динамическая типизация присуща в основном языкам интерпретируемым. В то время как строгая, свойственна компилируемым языкам.
Строгая типизация — это своего рода способ преждевременной оптимизации. Программист, пытается заранее решать проблемы теряя возможность изменять тип данных «на лету». Избыточный максимализм в случае с компилируемыми программами, объясняется ценой ошибки.
И цена бывает высока. Бывает очень высока. Особенно если ошибок много. Конечный пользователь получает продукт, который в процессе работы выдает фатальные ошибки, пишет в поддержку приложения. Служба поддержки передает обращения в отдел разработки ПО. Проходит время, программисты исправляют баги и предлагают пользователю обновить программу. Покупатель может потребовать деньги назад, что влечет финансовые потери для разработчиков. Исправить бинарные файлы скомпилированного приложения самостоятельно, пользователь само-собой не в состоянии.
Поэтому программисты предпочитают перестраховываться многократно, в том числе используя строгую типизацию, ошибки которой можно отловить еще на стадии компиляции. Увы, она не решает проблем «плохого кода» и ситуация описанная выше повторяется из раза в раз, из программы в программу.
Цена ошибки снижается, ели вы предоставляете конечному пользователю исходный код своей программы. Часто, пользователи в состоянии сами поправить ошибки, а затем прислать разработчикам свой вариант решения проблемы. Даже если конечный пользователь совсем не сведущ в программировании, всегда есть вариант нанять студента на бирже фриланса, который за 15 минут и пирожок, вернет программе работоспособность.
Так что утверждения о превосходстве компилируемых языков со строгой типизацией сильно преувеличены, как впрочем и стереотип о том, что плохой код присущ исключительно интерпретируемым языкам программирования.
Увы, но мозг человека, в отличии от компьютера, не способен синхронно выполнять несколько задач. Программист решая проблему, может не осознавать, что в процессе решения создает новые проблемы. Он сосредоточен на главной цели и описанном в ТЗ функционале, при этом он ограничен во времени.
Поэтому перестаньте поливать грязью друг-друга. Я видел много плохого кода, который решал задачи предприятий долгие годы и видел много красивых но бесполезных решений.
Реальные преимущества динамической типизации
- Простота создания универсальных коллекций.
- Легкость написания. Не нужно заморачиваться какие данные могут присутствовать в объекте или массиве, просто пользуемся ими.
- Низкий порог вхождения.
Реальные преимущества строгой (статической) типизации
- Проверки типов происходят один раз, на этапе компиляции.
- Скорость выполнения. Отсутствие необходимости дополнительных проверок может сильно ускорить работу, особенно в крупных проектах.
- Позволяет отлавливать ошибки еще на стадии компиляции (не все, не всегда).
Вот сводная табличка с Хабра, которая демонстрирует разницу в типизации различных языков, я немного расширил ее:
Язык | Статический? | Неявные преобразования? | Строгие правила? | Безопасный для памяти? |
---|---|---|---|---|
C | Сильный | Когда как | Слабый | Слабый |
C# | Сильный | Когда как | Сильный | Сильный |
Java | Сильный | Когда как | Сильный | Сильный |
Haskell | Сильный | Сильный | Сильный | Сильный |
Python | Слабый | Когда как | Слабый | Сильный |
PHP | Слабый | Когда как | Слабый | Сильный |
JavaScript | Слабый | Слабый | Слабый | Сильный |
(«Когда как» в колонке «Неявные преобразования» означает, что разделение между сильным и слабым зависит от того, какие преобразования мы считаем приемлемыми).
_________________________
НЕ В ТЕМУ: Ради этой статьи мне пришлось на время отложить статью о построении локального окружения на Docker. В ближайшие дни я выложу готовый текст, как оказалось, тема немного сложнее. Даже у меня, с моим относительно небольшим количеством проектов, требования к окружению могут различаться в зависимости от проекта. Так что статья потребовала дополнительного анализа.