О, чувак, я взволнован, чтобы попытаться ответить на этот вопрос как можно лучше. Надеюсь, я смогу привести свои мысли в порядок.
Как упоминал @Doval и спрашивающий указал (хотя и грубо), у вас на самом деле нет системы типов. У вас есть система динамических проверок с использованием тегов, которая в целом гораздо слабее, а также гораздо менее интересна.
Вопрос «что такое система типов» может быть довольно философским, и мы могли бы заполнить книгу различными точками зрения по этому вопросу. Однако, поскольку это сайт для программистов, я постараюсь сделать свой ответ максимально практичным (и действительно, типы являются чрезвычайно практичными в программировании, несмотря на то, что некоторые могут подумать).
обзор
Давайте начнем с понимания того, для чего нужна система типов, прежде чем углубляться в более формальные основы. Система типов накладывает структуру на наши программы . Они говорят нам, как мы можем соединить различные функции и выражения вместе. Без структуры программы являются несостоятельными и дико сложными, готовыми нанести вред при малейшей ошибке программиста.
Написание программ с системой типов - это как управление автомобилем в отличном состоянии: тормоза работают, двери закрываются, двигатель смазан и т. Д. Написание программ без системы типов - это как езда на мотоцикле без шлема и с колесами из спагетти. Вы абсолютно не контролируете себя.
Обосновать обсуждение, скажем , у нас есть язык с буквенным выражением num[n]
и str[s]
которые представляют цифру п и строку s, соответственно, и примитивные функции plus
и concat
, с подразумеваемым смыслом. Понятно, что вы не хотите писать что-то вроде plus "hello" "world"
или concat 2 4
. Но как мы можем предотвратить это? Априори нет способа отличить цифру 2 от строкового литерала «мир». Мы хотели бы сказать, что эти выражения должны использоваться в разных контекстах; у них есть разные типы.
Языки и типы
Давайте сделаем небольшой шаг назад: что такое язык программирования? В общем, мы можем разделить язык программирования на два уровня: синтаксис и семантика. Их также называют статикой и динамикой соответственно. Оказывается, что система типов необходима для взаимодействия между этими двумя частями.
Синтаксис
Программа это дерево. Не обманывайтесь строками текста, которые вы пишете на компьютере; это просто понятные человеку представления программы. Сама программа представляет собой абстрактное синтаксическое дерево . Например, в C мы могли бы написать:
int square(int x) {
return x * x;
}
Это конкретный синтаксис для программы (фрагмент). Представление дерева:
function square
/ | \
int int x return
|
times
/ \
x x
Язык программирования предоставляет грамматику , определяющий допустимые деревья этого языка (либо конкретного или абстрактного синтаксиса могут быть использованы). Обычно это делается с использованием чего-то вроде нотации BNF. Я предполагаю, что вы сделали это для языка, который вы создали.
Семантика
Хорошо, мы знаем, что такое программа, но это просто статическая древовидная структура. Предположительно, мы хотим, чтобы наша программа действительно что-то вычисляла . Нам нужна семантика.
Семантика языков программирования является богатой областью изучения. Вообще говоря, существует два подхода: денотационная семантика и операционная семантика . Денотационная семантика описывает программу, отображая ее в некоторую базовую математическую структуру (например, натуральные числа, непрерывные функции и т. Д.). это придает смысл нашей программе. Операционная семантика, напротив, определяет программу, детализируя, как она выполняется. На мой взгляд, операционная семантика более интуитивна для программистов (включая меня), поэтому давайте придерживаться этого.
Я не буду рассказывать, как определить формальную операционную семантику (детали немного задействованы), но в основном нам нужны такие правила:
num[n]
это значение
str[s]
это значение
- Если
num[n1]
и num[n2]
вычислить до целых чисел n_1$ and $n_2$, then
плюс (num [n1], num [n2]) `, то получится целое число $ n_1 + n_2 $.
- Если
str[s1]
и str[s2]
оценивает строки s1 и s2, то concat(str[s1], str[s2])
вычисляет строку s1s2.
И т.д. Правила на практике намного более формальны, но вы понимаете суть. Однако вскоре мы столкнемся с проблемой. Что происходит, когда мы пишем следующее:
concat(num[5], str[hello])
Гектометр Это довольно загадка. Мы нигде не определили правила для конкатенации числа со строкой. Мы могли бы попытаться создать такое правило, но мы интуитивно знаем, что эта операция не имеет смысла. Мы не хотим, чтобы эта программа была действительной. И поэтому нас неумолимо ведут к типам.
Типы
Программа - это дерево, определяемое грамматикой языка. Программы имеют смысл по правилам исполнения. Но некоторые программы не могут быть выполнены; то есть некоторые программы не имеют смысла . Эти программы плохо напечатаны. Таким образом, типизация характеризует значимые программы на языке. Если программа хорошо напечатана, мы можем ее выполнить.
Давайте приведем несколько примеров. Опять же, как и в случае с правилами оценки, я представлю правила набора текста неформально, но их можно сделать строгими. Вот несколько правил:
- Токен формы
num[n]
имеет тип nat
.
- Токен формы
str[s]
имеет тип str
.
- Если выражение
e1
имеет тип, nat
а выражение e2
имеет тип nat
, то выражение plus(e1, e2)
имеет тип nat
.
- Если выражение
e1
имеет тип, str
а выражение e2
имеет тип str
, то выражение concat(e1, e2)
имеет тип str
.
Таким образом, в соответствии с этими правилами plus(num[5], num[2])
есть тип имеет тип nat
, но мы не можем назначить тип plus(num[5], str["hello"])
. Мы говорим, что программа (или выражение) хорошо типизирована, если мы можем назначить ей любой тип, и иначе она плохо напечатана. Система типов является надежной, если все хорошо напечатанные программы могут быть выполнены. Хаскель - это звук; С не является.
Заключение
Есть и другие взгляды на типы. Типы в некотором смысле соответствуют интуиционистской логике, и их также можно рассматривать как объекты в теории категорий. Понимание этих связей увлекательно, но это не обязательно, если кто-то просто хочет написать или даже спроектировать язык программирования. Тем не менее, понимание типов как инструмента управления формированиями программ имеет важное значение для проектирования и разработки языка программирования. Я только поцарапал поверхность того, что могут выразить типы. Я надеюсь, что вы думаете, что они стоят того, чтобы включить их в ваш язык.