Это предназначено для разработчиков программного обеспечения, которые уже хорошо разбираются в этих темах, которые заинтересованы в том, чтобы подвергнуть сомнению и переосмыслить то, что, по их мнению, они уже знают, с целью расширить свой кругозор и улучшить свое мастерство. Предполагается, что вы уже знаете, что такое статически известные типы и известные во время выполнения, какие бывают явные и неявные типы и что такое разработка, управляемая тестированием. Предполагается, что вы знакомы с идеей, что существует множество мнений и споров о полезности этих вещей, что некоторым людям нравится делить языки на «языки сценариев» и языки без сценариев, и что у людей разные предпочтения между ними.

Споры о том, достаточно ли полезно явное объявление типов (явные статические типы) или даже то, чтобы они были известны неявно во время компиляции (неявные статические типы) вообще, по сравнению с типами, которые полностью неизвестны и не указаны до времени выполнения, основан на отсутствии глубоких вопросов о том, что такое тип. Это становится особенно очевидным в контексте параметров функции / метода. Как только вы начнете рассуждать о вещах вроде того, что такое тип и почему он имеет значение, споров не будет. Указание или немедленное указание типа переменных имеет так много преимуществ, а отсутствие этой информации делает код настолько расплывчатым и неопределенным, что по умолчанию предпочтение следует отдавать строгим типам. Я не скажу, что они абсолютно лучше во всех отношениях, для каждого сценария, но они должны быть вариантом по умолчанию, который мы предпочитаем.

Допустим, функция или метод принимает один параметр. Что эта функция может делать с параметром или что можно по этому поводу проанализировать? Смотря как. Но от чего это зависит? Это зависит от типа. Возможно, для параметра вызывается метод. Обычно это подразумевает, что есть некоторые предположения о типе. Вы не можете вызвать этот метод, если у этого типа нет этого метода. Обычно вы не можете или, по крайней мере, не должны использовать математические операторы с типом, который каким-либо образом не является числовым. Если в уме программиста, смотрящего или использующего этот код, возникают какие-либо вопросительные знаки, ни на один из них нельзя будет ответить, пока вы не узнаете что-то о типе параметра. Если вы хотите вызвать эту функцию, вы не знаете, что допустимо для передачи, пока не узнаете, какой тип она ожидает. Если вы передадите неправильный тип, ваш код в корне неверен.

Основная проблема с нежеланием, чтобы компилятор знал правильный тип и проблемы с типом отчета (или линтер аналогичного типа), - это недостаточное понимание преимуществ жестких ограничений и границ. Ограничения и границы создают свободу. Без гравитации мы не смогли бы ходить по земле. Конечно, это «ограничивает» нас землей, из-за чего нам трудно покинуть ее, но это ограничение создает свободу, возможность ходить куда угодно. Пока инструмент не знает, что это за тип, на самом деле ничего не известно, и на самом деле ничего не может произойти. Компилятор не может ничего правильно скомпилировать, не разбираясь в типах. Среда выполнения не знает, что запускать, не разбираясь в типах.

Многие утверждают, что в этом нет необходимости, если у вас есть автоматизированные тесты. Они говорят, что они будут проверять поведение, которое вас действительно волнует, и типы будут проверяться неявно этим, или что, пока поведение проверяется на правильность, типы в любом случае не имеют значения. Хотя все это технически верно, это не является анализом затрат на прибыль. Тип - это самая суть всего, что есть в коде. Наблюдение за типом и автоматическая проверка правильности его использования дает вам возможность работать, точно так же, как гравитация дает нам возможность работать. Видя тип параметра, код становится понятнее. Это накладывает некоторые ограничения на то, что это за вещь, прямо в том месте, где она определена. Это обеспечивает единообразие в том, где найти эту информацию. Это избавляет вас от необходимости немедленно смотреть либо на реализацию, либо на тест, чтобы начать что-либо знать об этом параметре.

Как может разум создавать (программировать) разумно, если он не хочет заботиться о самом важном или имеет какие-либо ограничения, которые создают систему отсчета для интерпретации вещей?

Мы живем в мире, который ценит свободу в ущерб свободе. Мы сосредотачиваемся только на недостатках ограничений, не видя положительных сторон. Мы не хотим, чтобы наложили какие-либо ограничения на то, что мы можем делать, и, таким образом, лишили себя возможности сделать что-либо важное или избежать чего-либо серьезного. Бесконечные возможности оставляют нас с усталостью от решений и низкой силой воли. Преимущества нескольких фундаментальных ограничений по умолчанию огромны.

Типы - это строительные блоки, ядро ​​вселенной кода. Конечно, программа неверна только потому, что ее типы используются правильно. Но программа определенно неверна, если типы используются совершенно недопустимым образом.

Типы - это ограничение, которое дает вам наибольшую отдачу от вложенных средств, наибольшую выгоду при наименьших затратах. Я не говорю, что другие ограничения не стоят вашего времени и усилий, но типы дают вам многое за немного или, по крайней мере, они делают многое возможным. Например, когда статически типизированная переменная используется совершенно недопустимым образом для этого типа, компилятор может вам это сказать. У автора компилятора есть возможность сделать это сообщение об ошибке очень удобным и информативным. Не все компиляторы будут это делать, но, по крайней мере, тип делает это возможным. Если вам нужно запустить все тесты и дождаться выполнения этой строки кода, а затем попытаться интерпретировать ошибку времени выполнения, которая может даже не быть сосредоточена на неправильном использовании типа, это не так быстро и полезно для обратной связи, как вы бы получили из-за удобной для пользователя ошибки компилятора.

Если многие люди убеждены, что преимущества написания тестов перевешивают затраты, насколько это верно в отношении написания типов? Тест - это ограничение и описание ожидаемого. Если тест не пройден, ограничение сработает, вы не должны снимать его, пока не пройдете его. При неправильном использовании типа возникает ограничение, и вы не можете / не должны компилировать и запускать код, пока это не будет исправлено. Но не обязательно иметь совершенно отдельное место (тест), где вы ставите все свои ограничения. Вы хотите связать свои ограничения с кодом, ограничения - это код, а типы прекрасно справляются с этим. Я не говорю, что все, что нам нужно, это типы, но они успешно выражают ограничения прямо внутри самого кода, как часть кода.

Насколько далеко мы можем это сделать? Какие расширяющие возможности ограничения лежат за пределами типов? Какие еще ограничения мы можем выразить прямо в коде, чтобы сделать его более выразительным и предоставить возможность для еще более автоматической проверки во время компиляции? Это вопросы, которые мы должны себе задать. Какие еще вопросы мы должны себе задать? Какие способы мы упустили, чтобы существенно упростить написание и чтение кода?