Макросы vs шаблоны

Aug 29, 2013 10:24

Продолжая дискуссию про метапрограммирование в D: http://thedeemon.livejournal.com/68456.htmlRead more... )

macros, scala

Leave a comment

akuklev August 29 2013, 15:21:32 UTC
Вопрос как всегда в том, что у нас дефолтный уровень и что мы эскейпим. Дефолтным уровнем всегда должно быть то, чего больше, что более по-существу важно при чтении. А это в зависимости от задачи может быть как метакод, так и рантаймкод. В теле макроса дефолтный уровень код макроса, а генерируемый код инклюдится в виде квазицитат. В темплейтах наоборот дефолтный уровень target-код, а метакод эскейпится словом static. Шош тут делать, разные задачи элегантнее делать по-разному. Ту, что ты привёл выше, темплейтами делать элегантнее. Естественно, тривиальные с точки зрения алгоритмики макросов задачи темплейтами делать кошерно и красиво ( ... )

Reply

atlanter August 29 2013, 16:15:11 UTC
Согласен. Короче, как обычно, нужно сделать и то и другое :)

Reply

ext_1178598 August 29 2013, 16:17:04 UTC
Это все вопрос исключительно выразительности макросистемы. Если можно раскрываться в макросы и квазицитаты, то можно сделать альтернативные макро-объявления, в которых дефолтным уровнем будет уровень рантайма.

Reply

thedeemon August 29 2013, 17:16:00 UTC
D не одним static if богат, там и "два вложенных цикла, да рекурсийка, да..." так же просто делаются. TypeTuple, раскрываемый в статике foreach по ним, рекурсивные шаблонные ф-ии и исполнение почти произвольного чистого кода при компиляции - это вам не старинные плюсовые темплейты.

Reply

ext_956459 August 29 2013, 20:31:36 UTC
а что будет, если R *тоже* зависит от каких-то членов или методов MyRange(R) напрямую или через цепочку типов? (в шаблонах плюсов у нас порядок в данном случае задается вручную (путем включения куда-то forward declaration, а куда-то полных деклараций), а в Д как?)

Reply

thedeemon August 30 2013, 04:54:22 UTC
А можно пример желаемого на псевдокоде?

Reply

ext_956459 August 31 2013, 18:14:35 UTC
пример высосан из пальца (в смысле, я не буду рассказывать, зачем такое может потребоваться на практике)

пусть у нас есть классы X и Y

нам нужно, чтобы при наличии в классе X поля x в классе Y появлялись определенные поля и метод foo, а при наличии в классе Y поля y в классе X появлялись определенные поля и метод bar

при этом очень желательно, но не обязательно, указать что X зависит от Y, а Y зависит от X - полностью это указать не получится, т.к. полная запись будет что-то вроде X>>> и никогда не закончится

Reply

thedeemon August 31 2013, 19:42:46 UTC
А, хороший вопрос. Порядок объявлений в D не важен, и вот такой код компилится:

class X {
int x;
static if (hasMember!(Y, "y"))
bool bar;
}

class Y {
string y;
//static if (hasMember!(X, "x"))
// byte foo;
}

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

Reply

ext_778487 November 2 2014, 01:50:04 UTC
А как насчет файлик прочитать? Или там ХМЛ распарсить? (в компайлтайме, естественно)

Reply

thedeemon November 2 2014, 10:03:12 UTC
Тоже легко.

enum s = import("file.xml"); // compile time string constant
Потом берешь Pegged и парсишь
https://github.com/PhilippeSigaud/Pegged
он в компайлтайме умеет применять только что описанные (в том же файле) грамматики.

Reply

ext_956459 August 29 2013, 20:29:14 UTC
> а на сложных делать пуро и сверху-вниз

а чуть подробнее?

Reply


Leave a comment

Up