Много хороших ответов, позвольте мне добавить:
Существуют ли существующие парадигмы программирования (для языков без типов), которые исключают необходимость использования или изобретения систем типов?
Самая важная парадигма, особенно в Erlang, такова: предположим, что тип верен, иначе допустим крах.Не пишите чрезмерно проверяющий параноидальный код, но предположите, что полученный вами ввод имеет правильный тип или правильный шаблон.Не пишите (есть исключения из этого правила, но в целом)
foo({tag, ...}) -> do_something(..);
foo({tag2, ...}) -> do_something_else(..);
foo(Otherwise) ->
report_error(Otherwise),
try to fix problem here...
Убейте последнее предложение и сразу выведите его из строя.Позвольте супервизору и другим процессам выполнить очистку (вы можете использовать monitors()
для вспомогательных процессов, чтобы узнать, когда произошел сбой).
Будьте точны, однако, .Напишите
bar(N) when is_integer(N) -> ...
baz([]) -> ...
baz(L) when is_list(L) -> ...
, если известно, что функция работает только с целыми числами или списками соответственно.Да, это проверка во время выполнения, но цель - передать информацию программисту.Кроме того, HiPE, как правило, используют подсказку для оптимизации и, по возможности, исключают проверку типов.Следовательно, цена может быть меньше, чем вы думаете.
Вы выбираете нетипизированный / динамически типизированный язык, поэтому цена, которую вы должны заплатить, заключается в том, что проверка типов и ошибки в конфликтах будут происходить во время выполнения.Как подсказывают другие посты, статически типизированный язык также не освобождается от некоторых проверок - система типов (обычно) является приближением доказательства правильности.В большинстве статических языков вы часто получаете информацию, которой вы не можете доверять.Этот вход преобразуется на «границе» приложения, а затем преобразуется во внутренний формат.Преобразование служит для обозначения доверия: с этого момента вещь была проверена, и мы можем предположить определенные вещи об этом.Сила и правильность этого предположения напрямую связаны с его сигнатурой типа и тем, насколько хорош программист в манипулировании статическими типами языка.
Существуют ли в других случаях общие рекомендации о том, как решать проблемы,статическая типизация решает в динамически типизированных языках (без злобного переизобретения типов)?
У Эрланга есть dialyzer
, который можно использовать для статического анализа и вывода типов ваших программ.Он не будет вызывать столько ошибок типа, как проверка типов, например, в Ocaml, но он также не будет "плакать волком": ошибка диализатора, несомненно, является ошибкой в программе.И это не будет отклонять программу, которая может работать нормально.Простой пример:
and(true, true) -> true;
and(true, _) -> false;
and(false, _) -> false.
Вызов and(true, greatmistake)
вернет false
, но статическая система типов отклонит программу, потому что из первой строки будет выводить, что сигнатура типа принимает логическое значение () значение как 2-й параметр.Диализатор, напротив, примет эту функцию и даст ей подпись (boolean (), term ()) -> boolean ().Это можно сделать, потому что нет необходимости защищать a priori от ошибки.Если есть ошибка, во время выполнения система проверит проверку типа, которая ее перехватит.