Статическая типизация на большинстве языков (ну, Java и друзья, я не рассматриваю здесь семейство Haskell) делает программы многословными и чрезмерно ограничивает их, с небольшой отдачей на уровне разработки. При установлении связи между двумя объектами важно то, какую роль они играют и какие обязанности они выполняют, а не какой у них тип, поэтому статическая типизация заставляет вас думать не на том уровне.
Что касается надежности, как и нулевых указателей, ошибки типов обычно вызывают катастрофические сбои довольно быстро, поэтому они никогда не останутся незамеченными в течение длительного времени. Так что ИМХО класс ошибок, предотвращаемых статической типизацией, не так уж интересен. С другой стороны, любой мог написать Tool.new( "Hammer", -42 )
, что было бы правильно при вводе, но отрицательный вес, вероятно, приведет к очень странному поведению без сбоев. Это потому, что роль этого аргумента - weight , который никогда не бывает отрицательным, и вы не можете выразить это простым числовым типом. Поэтому во время разработки действительно нужны не статические типы, а проверки или контракты, как в Eiffel.
Теперь рассмотрим непредвиденную эволюцию программного обеспечения: вы хотите интегрировать поддержку единиц СИ. Понимаете ли вы, почему проектное решение статической типизации этого параметра числом теперь выглядит преждевременным? В динамически типизированной системе проще создать новый объект, который знает арифметику, но учитывает преобразования единиц измерения, и использовать его непосредственно вместо чисел в существующем коде.
Конечно, статические типы имеют ценность для документации, а языки с динамической типизацией требуют некоторой дисциплины в этой области, а именно: четкое именование, хорошие тесты, хорошие комментарии ... но в любом случае ни один из них не является лишним со статической типизацией.