Я думаю, что вы спрашиваете о двух разных вещах.
- Способность языка программирования представлять все свои программы в виде данных.
- Рассуждая о программах как данных.
Для аналитических целей полезно держать их отдельно. Я сосредоточусь на первом.
Способность языков программирования представлять, манипулировать (и запускать) своими программами в качестве данных подпадает под такие термины, как метапрограммирование или
гомойконичность .
(Неловко), все известные языки программирования могут выполнять метапрограммирование, а именно, используя строковый тип данных вместе со способностью вызывать внешние программы (компилятор, компоновщик и т. Д.) Для строк (например, записывая их в файл система в первую очередь). Тем не менее, это, вероятно, не то, что вы имеете в виду. Вы, вероятно, имеете в виду хороший синтаксис. Строки не являются хорошим синтаксисом для представления программы, потому что почти все строки не представляют программы, т.е. строковый тип данных содержит много «мусора», когда рассматривается как механизм представления программы. Что еще хуже, алгебра строковых операций практически не имеет отношения к алгебре конструирования программ.
То, что вы, вероятно, имеете в виду, является чем-то более приятным. Например, если - это программа, то - это , но в качестве данных для манипуляций и анализа. Это часто называют цитатой . На практике цитата негибкая, поэтому мы используем вместо нее квази-цитату , которая является обобщением цитаты, где в цитате могут быть «дыры», в которых могут быть запущены программы, предоставляющие данные для «заполнения» дыр. Например, - это квази-кавычка, представляющая условие, где вместо условия у нас есть отверстиеп⟨ P⟩⟨ я еп
⟨ Я е[ ⋅ ]т ч е н7э л с е8 + 9 ⟩
М ⟨ х > 0 ⟩ ⟨ я е[ ⋅ ] . Если программа оценивает данные , то квази-цитата оценивается как данные
M⟨ Х > 0 ⟩⟨ я е⟨ Я е[ М]т ч е н7э л с е8 + 9 ⟩
⟨ Я ех > 0т ч е н7э л с е8 + 9 ⟩ .
(Обратите внимание, что - это обычная программа (не программа в качестве данных), которая возвращает программу в кавычках, то есть программу в качестве данных.) Чтобы это работало, вам нужен тип данных для представления программ. Обычно этот тип данных называется AST (абстрактное синтаксическое дерево), и вы можете видеть (квази) кавычки как механизмы сокращения для AST.M
Несколько языков программирования предлагают квази-кавычки и другие функции для метапрограммирования. Именно Lisp с его макро-функциональностью открыл эту возможность для обработки программ как данных. Возможно, к сожалению, сила макросов, основанных на Лиспе, долгое время основывалась на минималистическом синтаксисе Лиспа; только в MetaML (1) было показано, что современный, синтаксически богатый язык способен метапрограммировать. С тех пор MetaOCaml (2) (потомок MetaML, важен для своего прорыва в продолжающемся поиске решения проблемы ввода программ в виде данных), Template Haskell (3) и Converge (4) (первый язык для поймите, что все ключевые функции метапрограммирования были правильными) показали, что метапрограммирование может содержать множество современных языков программирования. Важно понимать, что мы можем принятьлюбой язык программирования и превратить его в язык метапрограммирования
который является вместе с возможностью представления (и оценки) своих собственных программ в качестве данных.L m p LLLм рL
Представление результатов работы программы, представленной в виде данных, достигается добавлением функции которая принимает программу (заданную как данные) в качестве входных данных и запускает ее , возвращая свой результат. Например, если - программа, оценивающая 17 и , (квази) цитируемая версия , то есть качестве данных, то также возвращает 17. Существуют все способы тонкости здесь, что я игнорирую здесь, такие как вопрос, когдаР ⟨ Р ⟩ Р Р е V л ( ⟨ Р ⟩ ) Р ⟨ Р ⟩e v a l (⋅)п⟨ P⟩ппе v L (⟨Р⟩ )метапрограммируемые программы оцениваются (что приводит к различию между метапрограммированием во время компиляции и во время выполнения), что делать с типами или с ошибочными оценками, что происходит со связанными и свободными переменными в процессе перехода от к или наоборот.п⟨ P⟩
Что касается второго измерения, рассуждения о программах приведены в виде данных. Как только вы можете конвертировать программы в данные, они становятся «нормальными» данными и могут быть обоснованы как данные. Вы можете использовать всевозможные технологии проверки, например, зависимые типы или контракты, интерактивные средства проверки теорем или автоматизированные инструменты, как указывал Джошуа. Однако вам придется представлять семантику вашего языка в процессе рассуждения. Если этот язык, как вам требуется, обладает способностями метапрограммирования, все может стать немного сложнее, и в этом направлении не было проделано большой работы, при этом (5) является единственной программной логикой для этой цели. Существует также работа Карри-Говарда, основанная на рассуждениях о метапрограммировании (6, 7, 8). Обратите внимание, что эти логические подходы, и основанный на типе подход (2) действительно может выражать свойства, которые сохраняются для всех будущих этапов метапрограммирования. Помимо (2) ни один из этих документов не был реализован.
Таким образом, то, что вы просили, было реализовано, но это довольно тонко, и есть все еще открытые вопросы, в частности, связанные с типами и оптимизированными рассуждениями.
У. Таха. Многоступенчатое программирование: его теория и приложения .
В. Таха и М. Ф. Нильсен. Классификаторы среды .
Т. Шеард и С. Пейтон Джонс. Шаблон метапрограммирования для Haskell .
Л. Тратт Мета-программирование во время компиляции на динамически типизированном ОО-языке .
М. Бергер, Л. Тратт, Программная логика для однородного метапрограммирования .
Р. Дэвис, Ф. Пфеннинг, Модальный анализ поэтапных вычислений .
Р. Дэвис, Временно-логический подход к анализу времени привязки .
Т. Цукада, А. Игараси. Логическая основа для классификаторов среды .