Не знаю, как это правильно назвать, но попробую описать желаемое.
В C# существуют анонимные типы, но они не видны за пределами скоупа. В Немерле ситуация с макросом new обстоит аналогичным образом. То есть функция, возвращающая анонимный тип, должна быть описана как object или IAnonymous. Я пытался обогнуть это ограничение, сделав макроатрибут [AnonReturnType], который должен был
— типизировать тело метода foo
— узнать какой тип сгенерировал макрос new
— рядом с исходным объявить еще один метод fooTyped с теми же самыми аргументами и типом, который сгенерировал new, в качестве возвращаемого
— скопировать тело исходного метода, заменив финальный new на конструктор желаемого типа (либо просто вызвать исходный метод и сделать каст к нужному типу)
Но, к сожалению, у меня ничего не получилось. Компилятор валился на попытке типизировать тело метода. Наверное, я что-то напутал со стадиями компиляции. У меня практически нет опыта в написании макросов, потому я не уверен, что подобное возможно.
Что скажете, реально?
Может мне лучше попробовать модифицировать new, чтобы он принимал необязательные аргументы: имя для генерируемого типа и надо ли генерировать типизированный вариант метода?
Здравствуйте, STDray, Вы писали:
STD>Что скажете, реально?
Бессмысленно.
STD>Может мне лучше попробовать модифицировать new, чтобы он принимал необязательные аргументы: имя для генерируемого типа и надо ли генерировать типизированный вариант метода?
Зачем? С таким же успехом можно в нужном пространстве имен описать требуемый класс.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Именованные анонимные типы
От:
Аноним
Дата:
11.10.12 20:54
Оценка:
H>Зачем? С таким же успехом можно в нужном пространстве имен описать требуемый класс.
Идея была как раз в том, чтобы руками класс не описывать. Анонимные типы, только не ограниченные споупом функции.
Здравствуйте, Аноним, Вы писали:
H>>Зачем? С таким же успехом можно в нужном пространстве имен описать требуемый класс.
А>Идея была как раз в том, чтобы руками класс не описывать. Анонимные типы, только не ограниченные споупом функции.
Это уже не анонимные типы. В дотнете нет штатного способа описать структурный тип, именно поэтому существуют Func<...>, Action<...>, Tuple<...> и их братья близнецы в Nemerle, только более тесно связанные с языком.
Попытка дать "анонимному" типу какое-то имя обернется жуткими проблемами из-за порядка типизации — тела методов типизируются после заголовков методов. Т.е. попытка написать некоторый анонимный тип в заголовке метода приведет к ошибке компиляции — тип не будет найден, так как тело метода еще не типизировалось. Конечно, эту проблему можно будет решить либо навешиванием на этот метод (аргумент, либо возвращаемое значение, с другой стороны не понятно что делать с генерик параметрами) некоторого атрибута либо расширением суждения компилятора о типах в нужном направлении, но все это будет выглядеть очень криво.
H>Это уже не анонимные типы. В дотнете нет штатного способа описать структурный тип, именно поэтому существуют Func<...>, Action<...>, Tuple<...> и их братья близнецы в Nemerle, только более тесно связанные с языком.
Про имя я, видимо, зря сказал. Если я правильно понял, как работает макрос new, то он создает типы в отдельном пространстве имен. Вот меня интересует, можно ли, работая на стадии компиляции после той, где работает new (либо в той же самой, если его модифицировать), создать клон метода, но с конкретным типом (созданным new) возвращаемого значения вместо IAnonymous.
Здравствуйте, STDray, Вы писали:
STD>Про имя я, видимо, зря сказал. Если я правильно понял, как работает макрос new, то он создает типы в отдельном пространстве имен. Вот меня интересует, можно ли, работая на стадии компиляции после той, где работает new (либо в той же самой, если его модифицировать), создать клон метода, но с конкретным типом (созданным new) возвращаемого значения вместо IAnonymous.
Непонятна цель
Нужно дождаться завершения типизации тела метода и смотреть что за тип получился, после этого можно добавлять новый метод в тип с модифицированной сигнатурой.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[6]: Именованные анонимные типы
От:
Аноним
Дата:
11.10.12 23:00
Оценка:
H>Непонятна цель
Цель — иметь информацию о структуре объекта даже за пределами метода.
H>Нужно дождаться завершения типизации тела метода и смотреть что за тип получился, после этого можно добавлять новый метод в тип с модифицированной сигнатурой.
У меня не вышло, компилятор падал при попытке типизации тела.
H>>>Непонятна цель А>>Цель — иметь информацию о структуре объекта даже за пределами метода.
H>Она достигается объявлением отдельного класса, это не так трудно (последующее сопровождение кода будет только легче): H>Мой опыт использования анонимных типов в C# показывает, что анонимные типы при последующей поддержке только мешают разбираться в коде.
Меня интересует техническая сторона вопроса. А уж приживется или нет покажет время. Не думаю, что я единственный, кто хотел бы пробросить анонимные типы за пределы скоупа функции. К тому же, это было бы очередной прекрасной демонстрацией возможностей немерлевых макросов.
Здравствуйте, STDray, Вы писали:
H>>>>Непонятна цель А>>>Цель — иметь информацию о структуре объекта даже за пределами метода.
H>>Она достигается объявлением отдельного класса, это не так трудно (последующее сопровождение кода будет только легче): H>>Мой опыт использования анонимных типов в C# показывает, что анонимные типы при последующей поддержке только мешают разбираться в коде.
STD>Меня интересует техническая сторона вопроса. А уж приживется или нет покажет время. Не думаю, что я единственный, кто хотел бы пробросить анонимные типы за пределы скоупа функции. К тому же, это было бы очередной прекрасной демонстрацией возможностей немерлевых макросов.
Я такое делал, но у меня особая ситуация, я использовал собранные типы только во вьюхах, которые компилировались в рантайме с рефернсом на основную сборку со сбилженными типами.
STD>Меня интересует техническая сторона вопроса. А уж приживется или нет покажет время. Не думаю, что я единственный, кто хотел бы пробросить анонимные типы за пределы скоупа функции. К тому же, это было бы очередной прекрасной демонстрацией возможностей немерлевых макросов.
, но дальше анализа глазами мест которые надо в компиляторе поправить ради её реализации не продвинулся — на прототип времени выделено было очень мало, и мне нужны были обе фичи. Если с синтаксисом не загоняться, то можно сделать ещё вот такие туплы из out'ов
[RewriteType3]
public Test(x: int): IAnonymous {
def a = new(A = x, B = "string");
a;
}
Типизировать ничего не выходит, к тому же ломается макрос new
...\Nemerle.MSBuild.targets(170,9): warning MSB3088:
Could not read state file "obj\Debug\ResolveMacroAssemblyReference.cache".
Exception has been thrown by the target of an invocation.
...\Main.n(29,2): warning : hint: start typing
...\Main.n(31,21): error : unbound name `x'
...\Main.n(31,13): error : wrong number of parameters in call, needed 0, got 2
confused by earlier errors bailing out
Подскажите, что я делаю не так и как мне все таки получить тип тела метода?
Здравствуйте, Аноним, Вы писали:
А>Типизировать ничего не выходит, к тому же ломается макрос new
А>
А>...\Nemerle.MSBuild.targets(170,9): warning MSB3088:
А>Could not read state file "obj\Debug\ResolveMacroAssemblyReference.cache".
А>Exception has been thrown by the target of an invocation.
А>...\Main.n(29,2): warning : hint: start typing
А>...\Main.n(31,21): error : unbound name `x'
А>...\Main.n(31,13): error : wrong number of parameters in call, needed 0, got 2
А> confused by earlier errors bailing out
А>
Все же в сообщениях об ошибке сказано.
А>Подскажите, что я делаю не так и как мне все таки получить тип тела метода?
Честно говоря все это через левое ухо сделано. Типизировать тело можно только специально созданным для этого тайпером.
И вообще, какова задача то?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>Все же в сообщениях об ошибке сказано.
В приведенном мною коде x вполне себе bound. Если снять с метода Test мой макроатрибут, все отработает отлично.
VD>Честно говоря все это через левое ухо сделано. Типизировать тело можно только специально созданным для этого тайпером.
Я понимаю, что ерунда. Где можно узнать про тайпер для тела метода?
VD>И вообще, какова задача то?
Узнать, какой тип сгенерировал макрос new. А потом действовать по плану, что я описал в оп-посте.
не помогло.
Точнее, если если в теле метода макрос new не используется, то все нормально.
А если используется, то любая попытка типизировать тело, кроме TryTyping, ломает его работу.
STD>Точнее, если если в теле метода макрос new не используется, то все нормально. STD>А если используется, то любая попытка типизировать тело, кроме TryTyping, ломает его работу.
Ну подскажите хоть в какую сторону смотреть. Начинать дебажить конпелятор, да?