?

Log in

No account? Create an account

Зачем нужны имплисит макросы? - Excelsior — LiveJournal

May. 7th, 2013

11:06 pm - Зачем нужны имплисит макросы?

Previous Entry Share Next Entry

Comments:

[User Picture]
From:thedeemon
Date:May 8th, 2013 05:04 am (UTC)
(Link)
Спасибо, очень внятно изложено.

В недавнем проекте на D у меня сериализация в бинарный поток произвольных объектов/структур/массивов из простых типов и других объектов/структур/массивов вылилась в несколько строк, вот они целиком:
void saveArray(T)(T[] arr, OutBuffer buf)
{
    int n = arr.length;
    buf.write(n);
    static if (isBasicType!T) 
        buf.write(cast(const(ubyte)[])arr);
    else 
        foreach(x; arr) save(x, buf);	
}

void save(T)(T x, OutBuffer buf)
{
    static if (isBasicType!T) buf.write(x);
    else
    static if (isArray!T) saveArray(x, buf);
    else			
    foreach(m; __traits(allMembers, T))
        static if ((m!="Monitor") && !isSomeFunction!(typeof(__traits(getMember, x, m))))
            save(__traits(getMember, x, m), buf);
}


Весь рефлекшон, проверки и циклы по мемберам раскрываются в компайл-тайме, в рантайме оказываются уже специализированные функции. Чтение обратно выглядит аналогично. Такой простоты больше нигде не видел.
(Reply) (Thread)
[User Picture]
From:xeno_by
Date:May 8th, 2013 07:08 am (UTC)
(Link)
Мартин очень положительно отзывается о простоте метапрограммирования в D. Кое-что оттуда, возможно, войдет в обновленный дизайн макросов в 2.11 или 2.12, но пока что о деталях говорить рано. Лично мне очень нравится идея адхок генерации кода при помощи mixin. Строки это, конечно, не фонтан, но сама возможность вколбасить куда хочешь что хочешь впечатляет.

Касательно твоего примера, как здесь с расширяемостью? Например, как добавить еще одно условие в кондишен if ((m!="Monitor") && ...)?
(Reply) (Parent) (Thread)
[User Picture]
From:thedeemon
Date:May 9th, 2013 05:07 pm (UTC)
(Link)
Вколбасить условие можно, вписав его туда. :) Это был маленький проект одного человека, о космической расширяемости мыслей не было.

Если начать задумываться, то можно заюзать атрибуты, например, и помечать ими детали для конкретных типов. Кажися, можно даже куски кода в атрибуты типов зафигачить, а в save() их извлекать и выполнять.
(Reply) (Parent) (Thread)