Языки, отличные от C++, для генеративного программирования?

StackOverflow https://stackoverflow.com/questions/116654

Вопрос

C++, вероятно, самый популярный язык для статическое метапрограммирование и Java его не поддерживает.

Существуют ли какие-либо другие языки, кроме C++, которые поддерживают генеративное программирование (программы, создающие программы)?

Это было полезно?

Решение

Альтернативой метапрограммированию в стиле шаблонов является стиль макросов, который вы видите в различных реализациях Lisp.Я бы предложил скачать Пол Грэм На Лиспе а также взглянем на Кложур если вас интересует Lisp с макросами, работающий на JVM.

Макросы в Lisp гораздо мощнее, чем стиль C/C++, и сами по себе представляют собой отдельный язык — они предназначены для метапрограммирования.

Другие советы

позвольте мне перечислить несколько важных деталей о том как метапрограммирование работает в шепелявости (или схема, или шифер, или выберите свой любимый «динамический» язык):

  • занимаясь метапрограммированием в Лиспе, вы не нужно иметь дело с двумя языками.код метауровня написан на том же языке, что и код объектного уровня, который он генерирует.метапрограммирование не ограничивается двумя уровнями, и оно также легче воздействует на мозг.
  • в Лиспе у вас есть компилятор доступен во время выполнения.на самом деле различие между временем компиляции и временем выполнения кажется здесь очень искусственным и во многом зависит от вашей точки зрения.в lisp простым вызовом функции вы можете скомпилировать функции в машинные инструкции, которые затем можно использовать как объекты первого класса;то естьэто могут быть безымянные функции, которые вы можете хранить в локальной переменной или глобальной хеш-таблице и т. д.
  • макросы в Лиспе очень просто:набор функций, помещенных в хеш-таблицу и переданных компилятору.для каждой формы, которую компилятор собирается скомпилировать, он обращается к этой хеш-таблице.если он находит функцию, то вызывает ее во время компиляции с исходной формой и вместо исходной формы компилирует форму, возвращаемую этой функцией.(по модулю некоторых несущественных деталей), поэтому макросы lisp по сути это плагины для компилятора.
  • написание функции Lisp на Lisp, которая оценивает код Lisp, занимает около двух страниц кода (обычно это называется оценивать).в такой функции у вас есть все возможности ввести на метауровне любые новые правила, которые вы захотите.(хотя заставить его работать быстро потребуются некоторые усилия...примерно то же самое, что загрузка нового языка...:)

случайные примеры того, что вы можете реализовать как пользовательскую библиотеку используя метапрограммирование Lisp (это реальные примеры распространенных библиотек Lisp):

  • расширить язык с помощью продолжения с разделителями (hu.dwim.delico)
  • реализовать js-to-lisp-rpc макрос, который вы можете использовать в javascript (который создается из lisp).он расширяется до смеси кода js/lisp, который автоматически отправляет (в HTTP-запросе) все указанные локальные переменные, декодирует их на стороне сервера, запускает тело кода lisp на сервере и возвращает возвращаемое значение в javascript сторона.
  • добавить пролог, например возврат к языку, который очень легко интегрируется с «обычным» кодом Lisp (см. Screamer)
  • а Расширение шаблонов XML в Common Lisp (включает пример макросы чтения это плагины для парсера lisp)
  • тонна маленьких DSL, типа петля или повторять для удобного зацикливания

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

Возиться с этим где-то в 98-м заставило меня искать лучшие решения.Я мог бы написать полезные системы, основанные на этом, но это был ад.Поиски в конечном итоге привели меня к Common Lisp.Конечно, механизм шаблонов является полным по Тьюрингу, но опять же, то же самое можно сказать и о интеркальном.

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

Конечно, есть и другие варианты.Ни один другой язык, который я использовал, не обеспечивает метапрограммирования лучше, чем Lisp, поэтому я использую его для исследования кода.Хотя есть много причин, по которым вам, возможно, захочется попробовать что-то еще, но все это будет компромиссом.Вы можете посмотреть Haskell/ML/OCaml и т. д.Многие функциональные языки имеют что-то вроде макросов Lisp.Вы можете найти некоторые материалы, ориентированные на .NET, но все они довольно маргинальны (с точки зрения пользовательской базы и т. д.).На самом деле ни у одного из крупных игроков на промышленно используемых языках нет ничего подобного.

Немерль и Бу мои личные фавориты в таких вещах.Nemerle имеет очень элегантный синтаксис макросов, несмотря на плохую документацию.Документация Boo превосходна, но ее макросы немного менее элегантны.Однако оба работают невероятно хорошо.

Оба ориентированы на .NET, поэтому могут легко взаимодействовать с C# и другими языками .NET, даже с двоичными файлами Java, если вы используете IKVM.

Редактировать:Чтобы уточнить, я имею в виду макросы в смысле этого слова в Lisp, а не макросы препроцессора C.Они позволяют определять новый синтаксис и тяжелое метапрограммирование во время компиляции.Например, Nemerle поставляется с макросами, которые будут проверять ваши SQL-запросы на вашем SQL-сервере во время компиляции.

Nim — относительно новый язык программирования, который имеет обширную поддержку статического метапрограммирования и создает эффективный (подобный C++) скомпилированный код.

http://nim-lang.org/

Он поддерживает оценку функций во время компиляции, преобразования кода AST в стиле LISP с помощью макросов, отражение во время компиляции, универсальные типы, которые можно параметризовать произвольными значениями, а также переписывание терминов, которое можно использовать для создания определяемых пользователем высокоуровневых типов с поддержкой типов. оптимизация глазка.В процессе компиляции можно даже запускать внешние программы, которые могут влиять на генерацию кода.В качестве примера рассмотрите возможность обращения к локально работающему серверу базы данных, чтобы убедиться, что определение ORM в вашем коде (поставляемое через некоторый DSL) соответствует схеме базы данных.

А язык программирования «Д». похож на C++, но имеет гораздо лучшую поддержку метапрограммирования.Вот пример трассировщика лучей, написанный с использованием только метапрограммирования времени компиляции:

Ctrace

Кроме того, существует ветвь gcc под названием «Concept GCC», которая поддерживает конструкции метапрограммирования, которых нет в C++ (по крайней мере, пока).

Концепция GCC

Common Lisp поддерживает программы, которые пишут программы несколькими различными способами.

1) Данные программы и «абстрактное синтаксическое дерево» программы однородны (S-выражения!)

2) defmacro

3) Макросы чтения.

4) СС

Из них настоящим потрясающим является MOP.Читайте «Искусство протокола мета -дюйма». Это изменит для вас, я обещаю!

Я рекомендую Хаскелл.Вот бумага описание его возможностей метапрограммирования во время компиляции.

Много работы в Haskell:Предметно-ориентированные языки (DSL), спецификации исполняемых файлов, преобразование программ, частичное применение, поэтапные вычисления.Несколько ссылок для начала:

Семейство языков ML было разработано специально для этой цели.Одна из самых известных историй успеха OCaml — это ФФТВ библиотека для высокопроизводительного БПФ, которая представляет собой код C, почти полностью созданный программой OCaml.

Ура, Джон Харроп.

Большинство людей пытаются найти язык, который имеет «окончательное размышление» для самостоятельности и что-то вроде «Eval» для повторного кода.Такие языки трудно найти (LISP является основным контрпримером), и они, конечно, не являются мейнстримом.

Но другой подход заключается в использовании набора инструментов, которые могут осматривать, генерировать и манипулировать кодом программы.Джекпот - такой инструмент, ориентированный на Java. http://jackpot.netbeans.org/

Наш инструментарий программного обеспечения DMS - это такой инструмент, который работает на C, C ++, C#, Java, Cobol, PHP, JavaScript, ADA, Verilog, VHDL и разнообразие других языков.(Он использует передние концы производства, чтобы он мог прочитать все эти лангаугу).Более того, он может делать это на нескольких языках одновременно.Видеть http://www.semdesigns.com/Products/DMS/DMSToolkit.html

DMS успешна, потому что она предоставляет стандартный метод и инфраструктуру поддержки для полного доступа к структуре программы в виде AST, а в большинстве случаев и к дополнительным данным, таким как таблицы символов, информация о типах, контроль и анализ потоков данных - все это необходимо для выполнения сложных манипуляций с программой.

«Метапрограммирование» на самом деле является плохим названием для этой конкретной функции, по крайней мере, когда вы обсуждаете более одного языка, поскольку эта функция необходима только для узкого круга языков, которые:

  • статический
  • скомпилирован в машинный язык
  • сильно оптимизирован для производительности во время компиляции
  • расширяемый с помощью определяемых пользователем типов данных (ООП в случае C++)
  • чрезвычайно популярный

уберите любой из них, и «статическое метапрограммирование» просто потеряет смысл.поэтому я был бы удивлен, если бы в каком-либо отдаленно распространенном языке было что-то подобное, как это понимается в C ++.

конечно, динамические языки и некоторые функциональные языки поддерживают совершенно разные концепции, которые также можно назвать метапрограммированием.

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

Мета-язык (ML), конечно: http://cs.anu.edu.au/student/comp8033/ml.html

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top