Примеры того, для чего можно использовать шаблоны D - PullRequest
21 голосов
/ 24 августа 2010

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

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

Ответы [ 4 ]

21 голосов
/ 24 августа 2010

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

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

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;
}

сценарий

foo bar xyz

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

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

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

21 голосов
/ 24 августа 2010

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

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

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

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

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

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

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

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

5 голосов
/ 29 августа 2010

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

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

5 голосов
/ 25 августа 2010

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

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