Подтвердить что ты не робот

Примеры того, какие шаблоны Ds можно использовать для

Я слышал, что язык D обладает мощными функциями метапрограммирования для выполнения функций во время компиляции. Это звучит очень интересно, но мне трудно думать о практических примерах вещей, которые трудно выполнить без них.

Может ли кто-нибудь привести примеры ситуаций, когда функции метапрограммирования D очень удобны?

4b9b3361

Ответ 1

Если вы хотите, чтобы практические примеры того, как использовать средства метапрограммирования D (CTFE, или оценка времени компиляции, являются лишь одним из них, а не даже самым важным), выглядят не дальше, чем в стандартной библиотеке Dobos. Большая часть этого кода написана Андреем Александреску, который изобрел множество методов метапрограммирования шаблонов на С++ и теперь работает с Уолтером Брайтом по дизайну и реализации D.

Лучшие модули для просмотра - std.range и std.algorithm. Они почти полностью состоят из шаблонов, были спроектированы Андреем и удивительно читаемы, учитывая количество метапрограммирования, которое они используют. Я внес значительный вклад в оба этих модуля и прочитал код, который был там, когда я начал, в основном, как я узнал.

Весь код лицензируется в соответствии с (чрезвычайно разрешительной) лицензией Boost и может быть просмотрен непосредственно из вашего браузера на сайте Phobos Trac на dsource.org.

Чтобы дать вам дорожную карту того, что вы смотрите, D средства метапрограммирования в основном делятся на 4 категории:

  • Шаблоны, которые в основном похожи на шаблоны С++, но с некоторыми дополнительными функциями, такими как static if, static assert, вариативные шаблоны и ограничения, которые в основном похожи на концепции, но более простые.

  • Отображение времени/интроспекция времени компиляции. Сюда входят встроенные выражения is() и __traits, а также стандартный библиотечный модуль std.traits.

  • Примеси. Они позволяют использовать шаблон (шаблоны mixins) или строку времени компиляции (string mixins) и оценивать ее как код в текущей области. String mixins можно рассматривать как нечто вроде выражения eval, за исключением того, что строка оценивается как код во время компиляции, а не во время выполнения.

  • Оценка функции времени компиляции или CTFE, которая позволяет выполнять функции, которые удовлетворяют определенным критериям, которые будут оцениваться во время компиляции. Одним из важных применений CTFE является то, что в сочетании со строковыми миксинами вы можете генерировать код как строку во время компиляции, а затем оценивать его как код в области, где выполняется оператор mixin. Для примера см. Std.range.Lockstep и std.range.OutputRangeObject, который я недавно проверил в релизах SVN для Phobos.

Ответ 2

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

Вот простой пример обработки файла во время компиляции.

main.d

string make_ints(string s)
{
    string ret = "";
    foreach (varname; split(s))
        ret ~= "int " ~ varname ~ "; ";
    return ret;
}

void main()
{
    mixin(make_ints(import("script")));
    foo = 1;
    bar = 2;
    xyz = 3;
}

script

foo bar xyz

Во время компиляции файл "script" будет считываться, разбиваться на пробелы, а затем make_ints возвращает int foo; int bar; int xyz; непосредственно в D-код, готовый для использования этих переменных.

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

Вы также можете использовать это для автоматической настройки производительности. Скажем, у вас есть постоянный X, который можно настроить, чтобы повлиять на производительность различными способами, но вы не знаете, какое значение X даст вам лучшую производительность. Вы можете поместить X в файл, прочитать его во время компиляции для использования, попробовать другие значения во время выполнения и перенести лучший из них в файл. Таким образом, вы постепенно улучшаете производительность, не делая ничего вручную.

Ответ 3

Я не хорошо разбираюсь в метапрограммах. Вот мой взгляд на три основные конструкции, найденные в D.

  • Оценка функции времени компиляции - это производительность. Создание компилятора делает как можно больше работы, так что меньше делается после запуска программы.
    • Как и создание кеша простых чисел, если вы его часто используете, используйте.
  • Шаблоны относятся к устранению дублирования алгоритма. Это не просто общее программирование, но поскольку D имеет CTFE, он не нужен в тех же случаях, что и С++.
  • Mixins - это возможность генерировать код во время компиляции, которое добавляется в программу. Он опирается на такие вещи, как шаблоны и CTFE, но все же важный элемент, не предоставленный другими.

Ответ 4

Практически интересное его использование, которое я знаю, это библиотека, которую я написал * для использования проверки типа для обеспечения безопасности устройства ( что запрещает добавлять расстояния до времени и обеспечивает правильное преобразование при добавлении метров в футы). То же самое можно сделать и было сделано на С++, но делать это в D во время компиляции немного сложнее, чем было бы делать это во время выполнения.

* извините за бесстыдный плагин.