Здравствуйте, Ziaw, Вы писали:
S>>Тут слегка о другом речь, метапрограммирование на атрибутах и макросы/квазицитирование — это всё-таки разные штуки и покрывают они разный набор задач. Разница — как между AOP и DSL, лучше их обсуждать по отдельности.
Z>Это только так кажется. Макрос в данном случае это код, который генерирует другой код. Как только люди начнут генерировать код в заметных объемах, сразу поймут, что без квазицитат это делать не так приятно. А какой это будет код, AOP или транслятор DSL — уже не важно, для начала нужен сам инструмент.
Ну блин, если постараться, то всё можно натянуть на один знаменатель, но это спор ради спора получается
Смотри сам: сила макросов (тут мы говорим о нормальных макросах уровня N или хотя бы c++ templates) — в навороченности. Минимально заменяемая единица — лексема, макросы можно комбинировать, переиспользовать, они могут расширять язык произвольным образом и в пределе — вообще превратить язык в человекочитаемый dsl.
Напротив, AOP на атрибутах — дубовая, простая и надёжная вещь. Минимальная область для реврайтера — член типа (поле/метод/свойство и тд). Т.е. сразу отпадает куча нюансов типа корректного раскрытия макроса, порядка применения, возни с синтаксическими конструкциями и тд и тп. Т.е. чисто функционально AOP на атрибутах беднее. Но для тех задач, где используется AOP это абсолютно неважно.
Цель aop — бороться с кодом, который слишком туп, чтобы его стоило писать вручную. Примеры — от списка полей для бэкенда формы и до реализации INotifyPropertyChanged. Короче, это compile-time замена сниппетам студии и действиям решарпера. Ну не нужны тут расширение синтаксиса, лёгкость описания макросов из самого языка, возможность сделать свой for, etc.
Зато за счёт этой простоты мы получаем применение макросов в реалтайме (для рослина с его «живым» редактором это важно), отсутствие проблем с версионностью (вплоть до у каждой сборки — свои реврайтеры), никаких вирусных макросов (когда клиентский код тоже вынужден использовать макросы) и идеальный порог вхождения — он достаточно высок, чтобы отсеять новичков и достаточно низок, чтобы не отпугнуть экспериментаторов.
В общем разница как между дубовым switch и полноценным паттерн-матчингом. Сценарии использования разные
S>>С _примититивным_ квазицитированием (только для избавления от генерации AST вручную) особых проблем тож нет,
Z>Генерация еще пол-беды. Вот когда люди помучаются с анализом AST без матчинга по квазицитатам, тогда станет понятно, что квазицитаты это офигеннейшая штука.
+ 100500. Одно но: для aop за глаза хватает того квазицитирования для бедных, что есть в рослине. Потому что там не требуется изменять произвольное AST, просто заменить пустышки готовой реализацией. Ну а если нужно что-то серьёзно большее, то надо смотреть на языки, в которых макросы есть с самого начала, а не вкорячены к (допустим) девятой версии
S>>Вектор не немерловый, ибо сценарии разные.
Z>Давай его назовем параллельным вектором, он и правда не немерловый, но направлен практически идентично.
По-моему нет. Немерль вместе с нитрой сейчас всё больше напоминает эдакий всемогутор для генерации dsl. Т.е. в принципе возможно всё, ошибся в дизайне — твой косяк.
C#, напротив, очень прагматичный язык, иногда даже чересчур. Куча вещей была выброшена из реализации только потому, что эти фичи можно использовать неправильно или они не проходят по соотношению затраты-выигрыш. За примерами ходить далеко не надо, смотрим на шестой шарп и вздыхаем по primary ctors и declaration expressions.