Я никогда не понимал таких утверждений, как этот. Если честно, даже если вы объявите тип возврата функции, вы можете и забудете ее после того, как написали много строк кода, и вам все равно придется вернуться к строке, в которой она объявлена с использованием функции поиска Ваш текстовый редактор, чтобы проверить это.
Речь идет не о том, что вы забыли тип возврата - это всегда будет происходить. Речь идет об инструменте, который может сообщить вам, что вы забыли тип возвращаемого значения.
Кроме того, поскольку функции объявляются с типом funcname()...
, без знания типа вам придется искать по каждой строке, в которой вызывается функция, потому что вы знаете funcname
, в то время как в Python и т. П. Вы можете просто искать def funcname
или function funcname
что происходит только один раз. На декларации.
Это вопрос синтаксиса, который совершенно не связан со статической типизацией.
Синтаксис семейства C действительно недружелюбен, когда вы хотите посмотреть объявление, не имея в своем распоряжении специализированных инструментов. Другие языки не имеют этой проблемы. Смотрите синтаксис объявления Rust:
fn funcname(a: i32) -> i32
Более того, с помощью REPL тривиально проверить функцию на возвращаемый тип с различными входными данными, в то время как со статически типизированными языками вам нужно будет добавить несколько строк кода и перекомпилировать все, чтобы узнать объявленный тип.
Любой язык может быть переведен, и любой язык может иметь REPL.
Итак, кроме того, чтобы знать тип возвращаемого значения функции, которая явно не является сильной стороной статически типизированных языков, как статическая типизация действительно полезна в больших проектах?
Я отвечу абстрактно.
Программа состоит из различных операций, и эти операции изложены так, как они есть, из-за некоторых предположений, которые делает разработчик.
Некоторые предположения являются неявными, а некоторые - явными. Некоторые предположения касаются операции рядом с ними, некоторые касаются операции вне их. Предположение легче определить, когда оно выражено явно и максимально близко к местам, где имеет значение его истинная ценность.
Ошибка - это проявление предположения, которое существует в программе, но не имеет места в некоторых случаях. Чтобы отследить ошибку, нам нужно выявить ошибочное предположение. Чтобы удалить ошибку, нам нужно либо удалить это предположение из программы, либо изменить что-то, чтобы это предположение действительно выполнялось.
Я хотел бы разделить предположения на два вида.
Первый тип - это предположения, которые могут или не могут быть выполнены, в зависимости от входных данных программы. Чтобы выявить ошибочные предположения такого рода, нам необходимо найти в пространстве все возможные входные данные программы. Используя обоснованные догадки и рациональное мышление, мы можем сузить проблему и искать в гораздо меньшем пространстве. Но, тем не менее, по мере того, как программа немного расширяется, ее начальное пространство ввода увеличивается с огромной скоростью - до такой степени, что ее можно считать бесконечной для всех практических целей.
Второй вид - это предположения, которые однозначно верны для всех входов или определенно ошибочны для всех входов. Когда мы определяем предположение такого рода как ошибочное, нам даже не нужно запускать программу или проверять какие-либо входные данные. Когда мы определили предположение такого рода как правильное, у нас меньше одного подозреваемого, чтобы заботиться о том, когда мы отслеживаем ошибку ( любую ошибку). Следовательно, имеет смысл иметь как можно больше предположений, относящихся к этому виду.
Чтобы поместить предположение во вторую категорию (всегда истинное или всегда ложное, независимо от входных данных), нам нужен минимальный объем информации, который должен быть доступен в месте, где сделано предположение. По всему исходному коду программы информация устареет довольно быстро (например, многие компиляторы не выполняют межпроцедурный анализ, что делает любой вызов жесткой границей для большей части информации). Нам нужен способ сохранить необходимую информацию свежим (действительным и рядом).
Один из способов заключается в том, чтобы источник этой информации был как можно ближе к месту, где она будет потребляться, но это может быть непрактичным для большинства случаев использования. Другой способ - часто повторять информацию, обновляя ее актуальность по всему исходному коду.
Как вы уже можете догадаться, статические типы - это как раз маяки информации о типах, разбросанные по всему исходному коду. Эта информация может быть использована для помещения большинства предположений о корректности типов во вторую категорию, что означает, что практически любая операция может быть классифицирована как всегда правильная или всегда неверная в отношении совместимости типов.
Когда наши типы неверны, анализ экономит наше время, так как предупреждает об ошибке раньше, чем поздно. Когда наши типы верны, анализ экономит наше время, гарантируя, что при возникновении ошибки мы можем немедленно исключить ошибки типов.