Это перевод статьи Даниэля Лебреро, которая также была опубликована на dev.to (там в комментариях есть интересное обсуждение на английском).
Меня удивил дядюшка Боб в посте под названием: "Type Wars". Он пишет: "Так что я предполагаю, что чем более общепринятой необходимостью профессиональной дисциплины будет становится TDD, тем более предпочтительными будут становится динамические языки. Smalltalker'ы постепенно победят".
Это утверждение не всем пришлось по душе. В сообществе сторонников статически-типизированных языков многие высказались, что достаточно продвинутая система типов (и типы — как доказательства) делает юнит-тесты ненужными. Haskell даже утверждает, что "если скомпилировалось, то обычно работает".
Будь это уменьшение багов, улучшенное документирование, более продвинутая поддержка IDE или простота понимания, для меня все это означает одно обещание: меньше багов.
А я ненавижу баги. Я считаю, что баги — одно из худших сжирателей времени и энергии в проекте. Нет ничего, что раздражает меня сильнее, чем слышать в демо в конце итерации гордое «мы сделали Х стори-пойнтов и исправили 20 багов! Ура!».
По мне так это звучит как «В прошлой итерации мы написали более 20 багов, но наши клиенты смогли найти лишь 20! И нам заплатили и за их написание, и за их исправление. Ура!»
Баги в графиках
С этим на уме, я попробовал найти какое-то эмпирическое основание идее «меньше багов в статических языках». К сожалению, лучший найденный мною источник говорит, что все очень плохо. Так что я согласился на более наивный способ: поиск в Github'е.
Вот несколько графиков сравнения числа issues с тегом "bug" и числа репозиториев на Github по разным языкам. Я постарался избавиться от шума, используя только репозитории с некоторым количеством звездочек (star), с допущением, что если нет звездочек, значит кодом никто не пользуется, и баги, соответственно, никто не находит.
Зеленый цвет — крутые, продвинутые статически-типизированные языки: Haskell, Scala and F#.
Оранжевый — "старые и скучные" статически-типизированные языки: Java, C++ and Go.
Красный — динамически-типизированные языки: JavaScript, Ruby, Python, Clojure and Erlang.
Раунд 1. Языки отсортированы по багам. Все репозитории.
Раунд 2. Языки отсортированы по багам. Репозитории с 10+ звезд.
Раунд 3. Языки отсортированы по багам. Репозитории с 100+ звезд.
Ничего нельзя утверждать, но сильно тревожит отсутствие какого-либо подтверждения меньшему количеству багов в продвинутых статических языках.
Проблема не в Static vs Dynamic
Графики показывают отсутствие корреляции между статичностью-динамичностью и багами. Но показывают (как минимум, по моему скромному мнению) пропасть между языками, фокусирующимися на простоте, и всеми остальными.
И Роб Пайк (создатель Go) и Рич Хики (создатель Clojure) проводили классные лекции о простоте как фундаментальной части своих языков.
И эта простота означает, что приложения легче понимать, легче изменять, легче поддерживать. Код — более гибкий. И все это означает меньше багов.
Что характеризует простой язык? Вот штуки, присущие Go, Erlang и Clojure:
- Нет ручного менеджмента памяти
- Нет параллельности, основанной на mutex'ах
- Нет классов
- Нет наследования
- Нет сложной системы типизации
- Нет мультипарадигм
- Не очень много синтаксиса
- Не академичный
Может, все эти модные штуки в наших языках на самом деле являются острыми инструментами, которыми мы раним себя — создаем баги и тратим время. И на самом деле они вносят кучу дополнительной сложности, а в реальности нам нужен более простой язык.
Как сказал Тони Хоар:
Есть два способа проработки дизайна приложения: один — сделать все настолько простым, что, очевидно, нет недостатков. Второй способ — сделать все настолько сложным, что нет очевидных недостатков.
Перевод: Рахим Давлеткалиев
P.S. Урок про типизацию из курса «Введение в программирование»