Фон
Я проектирую язык, как побочный проект. У меня есть рабочий ассемблер, статический анализатор и виртуальная машина для него. Поскольку я уже могу компилировать и запускать нетривиальные программы, используя созданную мной инфраструктуру, я подумал о том, чтобы выступить с презентацией в моем университете.
Во время моего выступления я упомянул, что виртуальная машина предоставляет систему типов, спросили: «Для чего нужна ваша система типов? ». После ответа мне посмеялся человек, задающий вопрос.
Таким образом, хотя я почти наверняка потеряю репутацию, задавая этот вопрос, я обращаюсь к программистам.
Мое понимание
Насколько я понимаю, системы типов используются для предоставления дополнительного уровня информации о сущностях в программе, чтобы среда выполнения, или компилятор, или любой другой компонент машин, знали, что делать со строками битов, над которыми он работает. Они также помогают поддерживать контракты - компилятор (или анализатор кода, или среда выполнения, или любая другая программа) может проверить, что в любой заданной точке программа оперирует значениями, которые программисты ожидают от нее.
Типы также могут быть использованы для предоставления информации этим программистам. Например, я нахожу это объявление:
function sqrt(double n) -> double;
более полезный, чем этот
sqrt(n)
Первый дает много информации: sqrt
идентификатор является функцией, принимает единицу в double
качестве входных данных и создает другой в double
качестве выходных данных. Последний говорит вам, что это, вероятно, функция, принимающая один параметр.
Мой ответ
Итак, после того, как вас спросили "Для чего нужна система типов?" Я ответил следующим образом:
Система типов является динамической (типы присваиваются значениям, а не переменным, содержащим их), но сильной без удивительных правил приведения (вы не можете добавить строку к целому числу, поскольку они представляют несовместимые типы, но вы можете добавить целое число к числу с плавающей запятой) ,
Система типов используется виртуальной машиной, чтобы гарантировать, что операнды для команд действительны; и может использоваться программистами, чтобы гарантировать, что параметры, переданные их функциям, действительны (то есть имеют правильный тип).
Система типов поддерживает подтипы и множественное наследование (обе функции доступны программистам), и типы учитываются, когда используется динамическая диспетчеризация методов для объектов - VM использует типы, чтобы проверить, какая функция данного сообщения реализована для данного типа.
Последующим вопросом было «А как тип присваивается значению?». Итак, я объяснил, что все значения упакованы и имеют указатель, указывающий на структуру определения типа, которая предоставляет информацию об имени типа, на какие сообщения он отвечает и от каких типов он наследует.
После этого мне посмеялись, и мой ответ был отклонен с комментарием «Это не настоящая система типов».
Итак, если то, что я описал, не квалифицируется как «настоящая система типов», что будет? Прав ли тот человек, что то, что я предоставляю, не может рассматриваться как система типов?
Ответы:
Все это похоже на точное описание того, что предоставляют системы типов. И ваша реализация звучит как достаточно разумная для того, что она делает.
Для некоторых языков вам не понадобится информация времени выполнения, поскольку ваш язык не выполняет диспетчеризацию во время выполнения (или вы выполняете одиночную диспетчеризацию через vtables или другой механизм, поэтому вам не нужна информация о типе). Для некоторых языков достаточно иметь символ / заполнитель, так как вы заботитесь только о равенстве типов, а не о его имени или наследовании.
В зависимости от вашей среды, человек, возможно, хотел больше формализма в вашей системе типов. Они хотят знать, что вы можете с этим доказать , а не то, что программисты могут сделать с этим. К сожалению, это довольно распространено в научных кругах. Хотя ученые делают такие вещи, потому что довольно легко иметь недостатки в вашей системе типов, которые позволяют вещам избежать правильности. Возможно, они заметили один из них.
Если у вас возникли дополнительные вопросы, « Типы и языки программирования» - это каноническая книга по этому предмету, которая может помочь вам изучить некоторые строгости, необходимые академикам, а также некоторые термины, помогающие описать вещи.
источник
a -> b
можно рассматривать как подразумеваемый b , т. е. если вы дадите мне значение типа,a
я смогу получить значение типаb
). Однако для того, чтобы это было согласованным, язык должен быть полным и, следовательно, не тьюринговым. Таким образом, все системы типов реальной жизни на самом деле определяют противоречивую логику.Мне нравится ответ @ Telastyn особенно из-за ссылки на академический интерес к формализму.
Позвольте мне добавить к обсуждению.
Система типов - это механизм для определения, обнаружения и предотвращения недопустимых состояний программы. Он работает путем определения и применения ограничений. Определения ограничений - это типы , а приложения ограничений - это использование типов , например, в объявлении переменной.
Определения типов обычно поддерживают операторы композиции (например, различные формы соединения, как в структурах, подклассах и дизъюнкции, как в перечислениях, объединениях).
Ограничения, использование типов, иногда также допускают операторы композиции (например, по крайней мере это, именно это, или то, или это, это при условии, что что-то еще выполняется).
Если система типов доступна на языке и применяется во время компиляции, чтобы иметь возможность выдавать ошибки во время компиляции, это статическая система типов; они предотвращают компиляцию многих нелегальных программ, не говоря уже о запуске, следовательно, предотвращают нелегальные состояния программ.
(Система статического типа останавливает выполнение программы, независимо от того, известно или нет (что она не может быть решена), что программа когда-либо достигнет того ненадежного кода, на который она жалуется. Система статического типа обнаруживает определенные виды бессмысленности (нарушения объявленных ограничений) и оценивает программу по ошибке до того, как она запустится.)
Если система типов применяется во время выполнения, это динамическая система типов, которая предотвращает недопустимые состояния программы: но останавливает программу в середине выполнения, вместо того, чтобы не запускать ее в первую очередь.
Довольно распространенным предложением системы типов является предоставление как статических, так и динамических функций.
источник
void *
указателей C (очень слабых), динамических объектов C # или экзистенциально количественных GADT на Haskell (которые дают вам довольно сильные гарантии, чем статически типизированные значения в большинстве других языки).О, чувак, я взволнован, чтобы попытаться ответить на этот вопрос как можно лучше. Надеюсь, я смогу привести свои мысли в порядок.
Как упоминал @Doval и спрашивающий указал (хотя и грубо), у вас на самом деле нет системы типов. У вас есть система динамических проверок с использованием тегов, которая в целом гораздо слабее, а также гораздо менее интересна.
Вопрос «что такое система типов» может быть довольно философским, и мы могли бы заполнить книгу различными точками зрения по этому вопросу. Однако, поскольку это сайт для программистов, я постараюсь сделать свой ответ максимально практичным (и действительно, типы являются чрезвычайно практичными в программировании, несмотря на то, что некоторые могут подумать).
обзор
Давайте начнем с понимания того, для чего нужна система типов, прежде чем углубляться в более формальные основы. Система типов накладывает структуру на наши программы . Они говорят нам, как мы можем соединить различные функции и выражения вместе. Без структуры программы являются несостоятельными и дико сложными, готовыми нанести вред при малейшей ошибке программиста.
Написание программ с системой типов - это как управление автомобилем в отличном состоянии: тормоза работают, двери закрываются, двигатель смазан и т. Д. Написание программ без системы типов - это как езда на мотоцикле без шлема и с колесами из спагетти. Вы абсолютно не контролируете себя.
Обосновать обсуждение, скажем , у нас есть язык с буквенным выражением
num[n]
иstr[s]
которые представляют цифру п и строку s, соответственно, и примитивные функцииplus
иconcat
, с подразумеваемым смыслом. Понятно, что вы не хотите писать что-то вродеplus "hello" "world"
илиconcat 2 4
. Но как мы можем предотвратить это? Априори нет способа отличить цифру 2 от строкового литерала «мир». Мы хотели бы сказать, что эти выражения должны использоваться в разных контекстах; у них есть разные типы.Языки и типы
Давайте сделаем небольшой шаг назад: что такое язык программирования? В общем, мы можем разделить язык программирования на два уровня: синтаксис и семантика. Их также называют статикой и динамикой соответственно. Оказывается, что система типов необходима для взаимодействия между этими двумя частями.
Синтаксис
Программа это дерево. Не обманывайтесь строками текста, которые вы пишете на компьютере; это просто понятные человеку представления программы. Сама программа представляет собой абстрактное синтаксическое дерево . Например, в C мы могли бы написать:
Это конкретный синтаксис для программы (фрагмент). Представление дерева:
Язык программирования предоставляет грамматику , определяющий допустимые деревья этого языка (либо конкретного или абстрактного синтаксиса могут быть использованы). Обычно это делается с использованием чего-то вроде нотации 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.И т.д. Правила на практике намного более формальны, но вы понимаете суть. Однако вскоре мы столкнемся с проблемой. Что происходит, когда мы пишем следующее:
Гектометр Это довольно загадка. Мы нигде не определили правила для конкатенации числа со строкой. Мы могли бы попытаться создать такое правило, но мы интуитивно знаем, что эта операция не имеет смысла. Мы не хотим, чтобы эта программа была действительной. И поэтому нас неумолимо ведут к типам.
Типы
Программа - это дерево, определяемое грамматикой языка. Программы имеют смысл по правилам исполнения. Но некоторые программы не могут быть выполнены; то есть некоторые программы не имеют смысла . Эти программы плохо напечатаны. Таким образом, типизация характеризует значимые программы на языке. Если программа хорошо напечатана, мы можем ее выполнить.
Давайте приведем несколько примеров. Опять же, как и в случае с правилами оценки, я представлю правила набора текста неформально, но их можно сделать строгими. Вот несколько правил:
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"])
. Мы говорим, что программа (или выражение) хорошо типизирована, если мы можем назначить ей любой тип, и иначе она плохо напечатана. Система типов является надежной, если все хорошо напечатанные программы могут быть выполнены. Хаскель - это звук; С не является.Заключение
Есть и другие взгляды на типы. Типы в некотором смысле соответствуют интуиционистской логике, и их также можно рассматривать как объекты в теории категорий. Понимание этих связей увлекательно, но это не обязательно, если кто-то просто хочет написать или даже спроектировать язык программирования. Тем не менее, понимание типов как инструмента управления формированиями программ имеет важное значение для проектирования и разработки языка программирования. Я только поцарапал поверхность того, что могут выразить типы. Я надеюсь, что вы думаете, что они стоят того, чтобы включить их в ваш язык.
источник