Re[13]: А не замутить ли AOP на основе R#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.12.04 22:32
Оценка:
Здравствуйте, gloomy rocker, Вы писали:

GR>Может такие куски кода можно помечать так?

GR>
GR>#region Meta.ID(ForEachArgument)
GR>    Console.WriteLine("Аргумент {0} = {1}", Argument.Name, Argument.Value);
GR>#endregion
GR>


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

Я тут подумал и мне пришла в голову одна мысль. В C# 2.0 появилась такая штука как анонимный метод (если кто не вкурсе, что цэ такое, читать здесь
Автор(ы): Владислав Чистяков (VladD2)
Дата: 24.06.2004
В статье рассказывается о новшествах, которые должны появиться в новой версии языка C#

).

Он поддеживает два варианта синтаксиса:
delegate(список параметров){ блок кода }
// и 
delegate{ блок кода }

Причем анонимный метод может быть использован как expansion (т.е. внутри выражения, передан в качестве параметра и т.п.).

Так же, по синтаксису C# 2.0, анонимный метод может ссылаться на переменные объявленные в блоках кода в которые вложено описание анонимного методы (об этом подробно расскзано в статье на которую я дал ссылку выше).


Таким образом достаточно ввести конструкцию вроде Meta.ForEach в которую передавать некую мета-коллекцию и анонимный метод (или имя мета-функции).

Например лог всех сообщений можно сделать таким образом:
void SomeAspect(...)
{
    Meta.ForEach(MetaMember.Arguments, delegate(object arg){ Debug.WriteLine(arg); })
    // Другой код сапекта
    @SomeAspect(MetaMember.Arguments); // вызов метода к которому подключается аспектный метод
    // Другой аспектный код...
}

Заметь, это 100% совместимая с C# 2.0 конструкция! Метод ForEach может быть реализован средсвами C# без каких бы то нибыло мухлеваний с переписыванием кода.
Например, вот реализация метода ForEach из штатного класса фрэймворка List<T>:
public void ForEach(Action<T> action)
{
      if (action == null)
      {
            ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
      }
      for (int num1 = 0; num1 < this._size; num1++)
      {
            action(this._items[num1]);
      }
}


Таким образом получится, что мы просто используем обычные конструкции C# для описания нужных нам мета-констркций.

Таким образом, мы можем разложить код приведенный в первом примере таким образом:
void SomeMethodWithAspect(int arg1, SomeClass arg2)
{
    { Debug.WriteLine(arg1); }
    { Debug.WriteLine(arg2); }
    // Другой код сапекта
    @SomeMethodWithAspect(arg1, arg2); // вызов метода к которому подключается аспектный метод
    // Другой аспектный код...
}


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

Кстати, с помощью знака "@" можно описывать вызов метода класса к которому производится подключение, а взовы без @ расценивать как обращение к коду аспекта расположенному в отдельном методе. Так всю нужную дрибиднь по выводу лога можно разместить в сервисном аспктном методе, который уже непосредственно использовать в коде аспкта.




Теперь по именам мета-расширений. Предлагаю следущий вариант.
Для обращению к мета-информации о классе к которому производится подключение использовать имя MetaType.
Для доступа к мета-информации о члене класса (а это может быть поле, свойство или метод) использовать MetaMember.
По идее список членов должен соотвествовать списку членов класса RTypeClass, RTypeStruct, RTypeInterface, RTypeDelegate или RTypeDelegate, в зависимости от того что за констркукция в данный момент обрабатывается.
Аналогично MetaMember должен соотвество RMemberMethodImpl, RMemberProperty и т.п.

Тогда у нас буде все нужные конструкции. Единственная разница между MetaType/MetaMember и классами AST будет в том, что их члены будут замещаться фактическими значениями конкретных классов.

Что касается Meta.ForEeach, то его можно рассматривать как метод которому передается одна из метаколлекций и делегат.

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

Кроме Meta.ForEach можно ввести такие конструкции как Meta.If, Meta.IfElse, Meta.Case, Meta.Inject.
Ниже я привел примерные декларации для этих конструкций:
// Если conditionExpr истинно встраивает в код целевого метода
// код из injectExpr. injectExpr может быть делегатом, выражением 
// или именем вспомогательного аспектного метода. 
Meta.If(RExpression conditionExpr, RExpression injectExpr);
// тоже что и предыдущее, но содержит так же выражение вставляемое в случе
// если выражение conditionExpr ложно.
Meta.IfElse(RExpression conditionExpr, RExpression trueInjectExpr, RExpression falseInjectExpr);
// Позволяет сделать множественный выбор (а-ля switch в C#, но в 
// функциональной форме).
// RExpressionPair - это пара из выражения сравниваемого с testExpr
// и выражения встраиваемого в случае если совопдения первого с testExpr
Meta.Case(RExpression testExpr, params RExpressionPair[] exprs); 
// Встраивает код из injectExpr в текущую точку. Если в injectExpr
// передано имя метода или безымянного метода, встраивается блок
// находящийся внутри метода, если это выражение, то оно просто подставляется
// в текущую точку.
Meta.Inject(RExpression injectExpr);


Таким образом мы получаем возможность полноценного метапрограммирования внутри методов целевой программы (причем пофигу будет ли это метод аспекта или просто метод класса).

Возможно я многое недодумал или изложил сумбурно, но мне кажется мы очень близки к очень красивому решению.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: А не замутить ли AOP на основе R#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.12.04 23:02
Оценка:
Здравствуйте, Sinclair, Вы писали:


S>Это хорошо. Но как ты собираешься использовать эти атрибуты в коде аспекта? Они ведь нужны не только для того, чтобы найти метод с нужной сигнатурой.

S>Ты не мог бы проиллюстрировать этот аспект хотя бы двухстрочным примером? А то мне кажется, что это суперуниверсальное решение будет трудновато использовать.

Атрибуты использовать ненадо. В аспекте испоьзуются псевда-прарметры. Например, pars1 будет массивом в который (виртуально) сложат все значения найденных запросом строковых параметров. В коде аспекта будет примерно такой код:
if (pars1[0] == "aaa")

в подставленном коде будет:
if (someStrArg == "aaa")

Ну, или код:
foreach (string str in pars1)

будет заменен на:
foreach (string str in new string[]{ arg1, arg3 })
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: А не замутить ли AOP на основе R#?
От: gloomy rocker Россия  
Дата: 10.12.04 16:58
Оценка: :)
Здравствуйте, VladD2, Вы писали:

К сожалению я сейчас не располагаю временем для анализа твоих идей (уволят блинн ), дома разберусь и поэкспериментирую.
Поверхностное изучение меня порадовало. От таких возможностей метапрограммирования аж дух захватило.

А пока вот мои наработки.
Тестовый проект. Просьба не бить сапогами по почкам за то что они ничего полезного не делает.
Реализация метаправила. Пока понимает только четко заданные сигнатуры.

Наверно стоит в репозитории создать ветку под RSharp.AOP. Чтобы энузиасты к нам толпой валили, и генерировали идеи.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Скука — двигатель прогресса.
Re[14]: А не замутить ли AOP на основе R#?
От: gloomy rocker Россия  
Дата: 10.12.04 17:06
Оценка:
Здравствуйте, VladD2, Вы писали:

И еще один вопрос. Нельзя ли сделать так, чтобы rsc генерировал полноценный проект, на который можно натравить тот же msbuild (или как он там называется), и получить готовую сборку? Для этого нужно будет в подкаталог .RSharp копировать все сопутствующие файлы типа ресурсов и т.д. А то создавать из сгенеренных файлов новый проект как-то лениво.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Скука — двигатель прогресса.
Re[15]: А не замутить ли AOP на основе R#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.12.04 19:47
Оценка:
Здравствуйте, gloomy rocker, Вы писали:

GR>Здравствуйте, VladD2, Вы писали:


GR>И еще один вопрос. Нельзя ли сделать так, чтобы rsc генерировал полноценный проект, на который можно натравить тот же msbuild (или как он там называется), и получить готовую сборку? Для этого нужно будет в подкаталог .RSharp копировать все сопутствующие файлы типа ресурсов и т.д. А то создавать из сгенеренных файлов новый проект как-то лениво.


Можно все что разумно.

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

Проблема только с тем, что это нужно делать. У меня сейчас со временем совсем плохо. Так что или займись сам, или пока обходись тем, что прокт в мсбилде может содержать просто ссылку на все файлы из подкаталога (поддерживаются вилдкарты, ну, там "*").
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: А не замутить ли AOP на основе R#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.12.04 19:47
Оценка:
Здравствуйте, gloomy rocker, Вы писали:

GR>Наверно стоит в репозитории создать ветку под RSharp.AOP. Чтобы энузиасты к нам толпой валили, и генерировали идеи.


Засунить не пролема. Есть только два замечания.
1. У тебя вроде нет логина. Так что шли мне на vc(эт)rsdn.ru логин и пароль, я добавлю.
2. Многие вещи из того, что ты называешь АОП я хотел бы видеть в более общих (да и в более узких) решениях. Я вообще сомневаюсь в том, что нужно выделять АОП как класс. Возможно лучшим решением было бы рассматривать идеи АОП как кодкласс идей мета-праграммирования.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: А не замутить ли AOP на основе R#?
От: gloomy rocker Россия  
Дата: 21.12.04 09:37
Оценка:
Появилась таки у меня минутка написать пару строк по теме.

В результате последних экспериментов у меня есть следующее.
Можно в коде аспекта ссылаться на трансформируемую сущьность примерно так
    Console.WriteLine("Вызван метод: {0}",MataUtil.Quote(MetaMember.Name));


Можно ссылаться так же на метаколлекции и обрабатывать их в цикле примерно так
    foreach(object arg in MetaMember.Parameters)
    {
        Console.WriteLine("name: {0}   value:{1}",MataUtil.Quote(arg.Name),arg.Name);
    }


Этот вариант мне показался красивее, чем через делегаты...
Для большей красивости можно было написать
    foreach(MetaParameter arg in MetaMember.Parameters)

но на процесс преобразования это не повлияет.

MetaUtil — это что-то типа набора макросов, чтобы можно было например простую строку взять в кавычки.
В данном случае это позволяет оперировать названиями аргументов и их значениями.

Пару слов о том, как это работает. В процессе преобразования находим все RMemberReference, у которых
TargetObject = 'MetaMember' или 'MetaUtil', дальше ориентируемся по контексту использования (исп. ref.Parent и ref.ParentNode)
Через рефлекшн находим нужную проперти или метод, ну а дальше создаем RPrimitiveExpression и подставляем его вместо ссылки.

Времени у меня сейчас в обрез, так что продолжение следует
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Скука — двигатель прогресса.
Re[15]: А не замутить ли AOP на основе R#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.12.04 21:40
Оценка:
Здравствуйте, gloomy rocker, Вы писали:

Я тоже постоянно думаю над вопросом и так как тема очень актуальная предлагаю вынести ее обсуждение в отдельную тему: Мысли о Метаязыке (Метакоде)
Автор: VladD2
Дата: 22.12.04
.

Там я довольно подробно остановился на проблемах связанных с внедрением некоего метаязыка и путях их решения.
... << RSDN@Home 1.1.4 beta 3 rev. 267>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: А не замутить ли AOP на основе R#?
От: remark Россия http://www.1024cores.net/
Дата: 28.06.05 20:27
Оценка:
Здравствуйте, gloomy rocker, Вы писали:

GR>Есть идея замутить сабж. Нечто типа Aspect#, только чтобы грамматика этого расширения укладывалась в грамматику C#.


А что такое АОП? Где можно почитать?
Это какая-то концепция? Или язык? Это реально работающая вещь, для которой есть примеры использования в серьёзных проектах?

Хотелось бы это поглядеть, потому что, как я понимаю, на текущий момент касательно R# нет такой полной концепции "метапрограммирование", как объектно-ориентированное программирование или структурное или логическое и т.д.
Т.е. когда я начинаю писать серьёзную программу, собираясь плотно использовать R#, нет никаких методик, концепций, правил декомпозиции предметной области, примеров, рекомендаций по организации метаправил. Т.е. вообще не понятно, что делать! В лучшем случае я могу выделить отдельный паттерн (типа визитор) и замутить его на R#.

Если я не прав, если всё это уже есть — поправьте меня.

И ещё вопрос — есть на данный какие-то аналоги R# (именно в смысле метапрограммирования)?

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: А не замутить ли AOP на основе R#?
От: Dr.Gigabit  
Дата: 29.06.05 17:49
Оценка: 34 (2) +1
Здравствуйте, remark, Вы писали:

R>Здравствуйте, gloomy rocker, Вы писали:


GR>>Есть идея замутить сабж. Нечто типа Aspect#, только чтобы грамматика этого расширения укладывалась в грамматику C#.


R>А что такое АОП? Где можно почитать?

R>Это какая-то концепция? Или язык? Это реально работающая вещь, для которой есть примеры использования в серьёзных проектах?

здесь и дальше по ссылкам

R>Хотелось бы это поглядеть, потому что, как я понимаю, на текущий момент касательно R# нет такой полной концепции "метапрограммирование", как объектно-ориентированное программирование или структурное или логическое и т.д.

R>Т.е. когда я начинаю писать серьёзную программу, собираясь плотно использовать R#, нет никаких методик, концепций, правил декомпозиции предметной области, примеров, рекомендаций по организации метаправил. Т.е. вообще не понятно, что делать! В лучшем случае я могу выделить отдельный паттерн (типа визитор) и замутить его на R#.

Имхо, сначало нужно определиться, надо ли это вам. Если да — то зачем? Тот же R#, на сколько я могу судить, решает многие задачи АОП гораздо элегантнее, чем все "родные" фрэймфорки, в том числе и из мира Java.
А что касается метапрограммирования, то концепция это существует уже достаточно давно, но R# просто привносит новые фичи в эту концепцию и ее реализацию на C#.

R>Если я не прав, если всё это уже есть — поправьте меня.


R>И ещё вопрос — есть на данный какие-то аналоги R# (именно в смысле метапрограммирования)?

Если именно в смысле метапрограммирования, то С++
Minsk .NET Alliance http://minsk.gotdotnet.ru
Re[3]: А не замутить ли AOP на основе R#?
От: remark Россия http://www.1024cores.net/
Дата: 29.06.05 19:03
Оценка:
Здравствуйте, Dr.Gigabit, Вы писали:

DG>Здравствуйте, remark, Вы писали:


R>>Здравствуйте, gloomy rocker, Вы писали:


GR>>>Есть идея замутить сабж. Нечто типа Aspect#, только чтобы грамматика этого расширения укладывалась в грамматику C#.


R>>А что такое АОП? Где можно почитать?

R>>Это какая-то концепция? Или язык? Это реально работающая вещь, для которой есть примеры использования в серьёзных проектах?

DG>здесь и дальше по ссылкам


thnx

R>>Хотелось бы это поглядеть, потому что, как я понимаю, на текущий момент касательно R# нет такой полной концепции "метапрограммирование", как объектно-ориентированное программирование или структурное или логическое и т.д.

R>>Т.е. когда я начинаю писать серьёзную программу, собираясь плотно использовать R#, нет никаких методик, концепций, правил декомпозиции предметной области, примеров, рекомендаций по организации метаправил. Т.е. вообще не понятно, что делать! В лучшем случае я могу выделить отдельный паттерн (типа визитор) и замутить его на R#.

DG>Имхо, сначало нужно определиться, надо ли это вам. Если да — то зачем? Тот же R#, на сколько я могу судить, решает многие задачи АОП гораздо элегантнее, чем все "родные" фрэймфорки, в том числе и из мира Java.

DG>А что касается метапрограммирования, то концепция это существует уже достаточно давно, но R# просто привносит новые фичи в эту концепцию и ее реализацию на C#.

Надо. Меня интересует вопрос так сказать "языка будущего". Все технологии программирования уже достаточно стары. Наиболее распространённая технология — ООП — сколько ей? лет 30? или больше? Когда она появилась — это было действительно что-то новое. Потом она развивалась. Сейчас находится на пике развития. Но пора и честь знать
И сейчас многие это понимают. Например, люди, которые занимаются R#...
Наверное, не стоит эту тему дальше в данном топике развивать.


R>>Если я не прав, если всё это уже есть — поправьте меня.


R>>И ещё вопрос — есть на данный какие-то аналоги R# (именно в смысле метапрограммирования)?

DG>Если именно в смысле метапрограммирования, то С++

С++??? Я начинаю приходить к выводу, что большинство людей под термином "метапрограммирование" понимает гораздо более приземлённые вещи Нет, меня интересует что-то типа, ну хотя бы атрибутов C# или, действительно, модификация кода как в R#. Что-то принципиально новое.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: А не замутить ли AOP на основе R#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.06.05 10:02
Оценка:
Здравствуйте, remark, Вы писали:

R>Здравствуйте, gloomy rocker, Вы писали:


GR>>Есть идея замутить сабж. Нечто типа Aspect#, только чтобы грамматика этого расширения укладывалась в грамматику C#.


R>А что такое АОП? Где можно почитать?


Аспектно Ориентированное Программирование. Кратенько про это сказано во водной статье по R#-у. Более развернуто можно найти в википедии и поиском по этому сайту и гуглю.

R>Т.е. когда я начинаю писать серьёзную программу, собираясь плотно использовать R#, нет никаких методик, концепций, правил декомпозиции предметной области, примеров, рекомендаций по организации метаправил. Т.е. вообще не понятно, что делать! В лучшем случае я могу выделить отдельный паттерн (типа визитор) и замутить его на R#.


R# — это средство. Молодое средство... Так что со временем ве будет. Был бы жив проект.

R>И ещё вопрос — есть на данный какие-то аналоги R# (именно в смысле метапрограммирования)?


OpenC++, OpenJava. Ну, и в какой-то мере все фрэймворки и утилиты метапрограммирования.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: А не замутить ли AOP на основе R#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.06.05 11:21
Оценка:
Здравствуйте, remark, Вы писали:

R>С++??? Я начинаю приходить к выводу, что большинство людей под термином "метапрограммирование" понимает гораздо более приземлённые вещи Нет, меня интересует что-то типа, ну хотя бы атрибутов C# или, действительно, модификация кода как в R#. Что-то принципиально новое.


С++ действительно позволяет с помощью некоторых приемов генерировать код во время компиляции. До полноценного мета-средства ему конечно очень долеко, но и то что есть позволяет нехило модифицировать язык. Достаточно глянуть на boost...

Однако есть языки где метапрограммирование не побочная плохо развитая фича. Например, таким языком является Лисп и его макросы (макросами их можно назвать только условно). Если бы не экзотичность данного средства оно имело бы хорошее будущее.

R# же. Это попытка привнести метапрограммирование в язык где его действительно нехватало.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.