Именованные анонимные типы
От: STDray http://stdray.livejournal.com
Дата: 11.10.12 20:16
Оценка:
Не знаю, как это правильно назвать, но попробую описать желаемое.
В C# существуют анонимные типы, но они не видны за пределами скоупа. В Немерле ситуация с макросом new обстоит аналогичным образом. То есть функция, возвращающая анонимный тип, должна быть описана как object или IAnonymous. Я пытался обогнуть это ограничение, сделав макроатрибут [AnonReturnType], который должен был
— типизировать тело метода foo
— узнать какой тип сгенерировал макрос new
— рядом с исходным объявить еще один метод fooTyped с теми же самыми аргументами и типом, который сгенерировал new, в качестве возвращаемого
— скопировать тело исходного метода, заменив финальный new на конструктор желаемого типа (либо просто вызвать исходный метод и сделать каст к нужному типу)
Но, к сожалению, у меня ничего не получилось. Компилятор валился на попытке типизировать тело метода. Наверное, я что-то напутал со стадиями компиляции. У меня практически нет опыта в написании макросов, потому я не уверен, что подобное возможно.
Что скажете, реально?
Может мне лучше попробовать модифицировать new, чтобы он принимал необязательные аргументы: имя для генерируемого типа и надо ли генерировать типизированный вариант метода?
Re: Именованные анонимные типы
От: hardcase Пират http://nemerle.org
Дата: 11.10.12 20:52
Оценка:
Здравствуйте, STDray, Вы писали:

STD>Что скажете, реально?


Бессмысленно.

STD>Может мне лучше попробовать модифицировать new, чтобы он принимал необязательные аргументы: имя для генерируемого типа и надо ли генерировать типизированный вариант метода?


Зачем? С таким же успехом можно в нужном пространстве имен описать требуемый класс.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Именованные анонимные типы
От: Аноним  
Дата: 11.10.12 20:54
Оценка:
H>Зачем? С таким же успехом можно в нужном пространстве имен описать требуемый класс.

Идея была как раз в том, чтобы руками класс не описывать. Анонимные типы, только не ограниченные споупом функции.
Re[3]: Именованные анонимные типы
От: hardcase Пират http://nemerle.org
Дата: 11.10.12 21:06
Оценка:
Здравствуйте, Аноним, Вы писали:

H>>Зачем? С таким же успехом можно в нужном пространстве имен описать требуемый класс.


А>Идея была как раз в том, чтобы руками класс не описывать. Анонимные типы, только не ограниченные споупом функции.


Это уже не анонимные типы. В дотнете нет штатного способа описать структурный тип, именно поэтому существуют Func<...>, Action<...>, Tuple<...> и их братья близнецы в Nemerle, только более тесно связанные с языком.
Попытка дать "анонимному" типу какое-то имя обернется жуткими проблемами из-за порядка типизации — тела методов типизируются после заголовков методов. Т.е. попытка написать некоторый анонимный тип в заголовке метода приведет к ошибке компиляции — тип не будет найден, так как тело метода еще не типизировалось. Конечно, эту проблему можно будет решить либо навешиванием на этот метод (аргумент, либо возвращаемое значение, с другой стороны не понятно что делать с генерик параметрами) некоторого атрибута либо расширением суждения компилятора о типах в нужном направлении, но все это будет выглядеть очень криво.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: Именованные анонимные типы
От: STDray http://stdray.livejournal.com
Дата: 11.10.12 21:14
Оценка:
H>Это уже не анонимные типы. В дотнете нет штатного способа описать структурный тип, именно поэтому существуют Func<...>, Action<...>, Tuple<...> и их братья близнецы в Nemerle, только более тесно связанные с языком.

Про имя я, видимо, зря сказал. Если я правильно понял, как работает макрос new, то он создает типы в отдельном пространстве имен. Вот меня интересует, можно ли, работая на стадии компиляции после той, где работает new (либо в той же самой, если его модифицировать), создать клон метода, но с конкретным типом (созданным new) возвращаемого значения вместо IAnonymous.
Re[5]: Именованные анонимные типы
От: hardcase Пират http://nemerle.org
Дата: 11.10.12 21:33
Оценка:
Здравствуйте, STDray, Вы писали:

STD>Про имя я, видимо, зря сказал. Если я правильно понял, как работает макрос new, то он создает типы в отдельном пространстве имен. Вот меня интересует, можно ли, работая на стадии компиляции после той, где работает new (либо в той же самой, если его модифицировать), создать клон метода, но с конкретным типом (созданным new) возвращаемого значения вместо IAnonymous.


Непонятна цель
Нужно дождаться завершения типизации тела метода и смотреть что за тип получился, после этого можно добавлять новый метод в тип с модифицированной сигнатурой.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[6]: Именованные анонимные типы
От: Аноним  
Дата: 11.10.12 23:00
Оценка:
H>Непонятна цель
Цель — иметь информацию о структуре объекта даже за пределами метода.

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

У меня не вышло, компилятор падал при попытке типизации тела.
Re[7]: Именованные анонимные типы
От: hardcase Пират http://nemerle.org
Дата: 11.10.12 23:08
Оценка:
Здравствуйте, Аноним, Вы писали:

H>>Непонятна цель

А>Цель — иметь информацию о структуре объекта даже за пределами метода.

Она достигается объявлением отдельного класса, это не так трудно (последующее сопровождение кода будет только легче):
[Record, StructuralEquality, StructuralHashCode]
public sealed class FooBar
{
  public X : int { get }
  public Y : int { get }
}


Мой опыт использования анонимных типов в C# показывает, что анонимные типы при последующей поддержке только мешают разбираться в коде.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[8]: Именованные анонимные типы
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.10.12 16:59
Оценка: 2 (1) +1
Здравствуйте, hardcase, Вы писали:

H>
H>[Record, StructuralEquality, StructuralHashCode]
H>public sealed class FooBar
H>{
H>  public X : int { get }
H>  public Y : int { get }
H>}
H>


Можно для сокращения объявления подобных типов завести макрос Data. Тогда бы объявление сократилось бы до:

data FooBar(X : int, Y : int);

или
data FooBar { X : int, Y : int };
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Именованные анонимные типы
От: Ziaw Россия  
Дата: 12.10.12 19:54
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Можно для сокращения объявления подобных типов завести макрос Data. Тогда бы объявление сократилось бы до:


VD>
VD>data FooBar(X : int, Y : int);
VD>

VD>или
VD>
VD>data FooBar { X : int, Y : int };
VD>


А что, уже разрешены синтаксические макросы уровня декларации класса?
Re[8]: Именованные анонимные типы
От: STDray http://stdray.livejournal.com
Дата: 12.10.12 20:06
Оценка:
H>>>Непонятна цель
А>>Цель — иметь информацию о структуре объекта даже за пределами метода.

H>Она достигается объявлением отдельного класса, это не так трудно (последующее сопровождение кода будет только легче):

H>Мой опыт использования анонимных типов в C# показывает, что анонимные типы при последующей поддержке только мешают разбираться в коде.

Меня интересует техническая сторона вопроса. А уж приживется или нет покажет время. Не думаю, что я единственный, кто хотел бы пробросить анонимные типы за пределы скоупа функции. К тому же, это было бы очередной прекрасной демонстрацией возможностей немерлевых макросов.
Re[10]: Именованные анонимные типы
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.10.12 21:54
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>А что, уже разрешены синтаксические макросы уровня декларации класса?


Лет 5 как. Интеллисенст, правда, не работает для них.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Именованные анонимные типы
От: Ziaw Россия  
Дата: 13.10.12 03:41
Оценка:
Здравствуйте, STDray, Вы писали:

H>>>>Непонятна цель

А>>>Цель — иметь информацию о структуре объекта даже за пределами метода.

H>>Она достигается объявлением отдельного класса, это не так трудно (последующее сопровождение кода будет только легче):

H>>Мой опыт использования анонимных типов в C# показывает, что анонимные типы при последующей поддержке только мешают разбираться в коде.

STD>Меня интересует техническая сторона вопроса. А уж приживется или нет покажет время. Не думаю, что я единственный, кто хотел бы пробросить анонимные типы за пределы скоупа функции. К тому же, это было бы очередной прекрасной демонстрацией возможностей немерлевых макросов.


Я такое делал, но у меня особая ситуация, я использовал собранные типы только во вьюхах, которые компилировались в рантайме с рефернсом на основную сборку со сбилженными типами.
Re[9]: Именованные анонимные типы
От: hi_octane Беларусь  
Дата: 14.10.12 11:14
Оценка:
STD>Меня интересует техническая сторона вопроса. А уж приживется или нет покажет время. Не думаю, что я единственный, кто хотел бы пробросить анонимные типы за пределы скоупа функции. К тому же, это было бы очередной прекрасной демонстрацией возможностей немерлевых макросов.

Я уже поднимал похожую тему
Автор: hi_octane
Дата: 14.02.11
, но дальше анализа глазами мест которые надо в компиляторе поправить ради её реализации не продвинулся — на прототип времени выделено было очень мало, и мне нужны были обе фичи. Если с синтаксисом не загоняться, то можно сделать ещё вот такие туплы из out'ов
Автор: hi_octane
Дата: 06.03.11
.

В целом сложилось впечатление что сделать это именно в том синтаксисе, без дополнительных ключевых слов вполне реально за неделю максимум.
Re: Почему не удается типизировать?
От: Аноним  
Дата: 17.10.12 20:47
Оценка:
Написал следующий нехитрый код

[MacroUsage(MacroPhase.WithTypedMembers, MacroTargets.Method)]
macro RewriteType3(typeBuilder : TypeBuilder, method : MethodBuilder) {
    RewriteTyp3Impl.DoTransform(Macros.ImplicitCTX(), typeBuilder, method)
}

module RewriteTyp3Impl {
    public DoTransform(typer : Typer, _ : TypeBuilder, method : MethodBuilder) : void {
        Macros.DefineCTX(typer);
        Message.Hint("start typing");
        def tExpr = typer.TypeExpr(method.Body);
        Message.Hint("slow...");
        _ = typer.DelayMacro(fun (lastTry) {
            if(lastTry && tExpr.Type.Hint.IsNone) Message.Hint("type unknown"); 
            else                                  Message.Hint($"$tExpr"); 
            None()
        });
        Message.Hint("end typing");
    }
}


использую так

[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


Подскажите, что я делаю не так и как мне все таки получить тип тела метода?
Re[2]: Почему не удается типизировать?
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.10.12 00:33
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Типизировать ничего не выходит, к тому же ломается макрос 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
А>


Все же в сообщениях об ошибке сказано.

А>Подскажите, что я делаю не так и как мне все таки получить тип тела метода?


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

И вообще, какова задача то?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Почему не удается типизировать?
От: STDray http://stdray.livejournal.com
Дата: 18.10.12 00:50
Оценка:
VD>Все же в сообщениях об ошибке сказано.
В приведенном мною коде x вполне себе bound. Если снять с метода Test мой макроатрибут, все отработает отлично.

VD>Честно говоря все это через левое ухо сделано. Типизировать тело можно только специально созданным для этого тайпером.

Я понимаю, что ерунда. Где можно узнать про тайпер для тела метода?

VD>И вообще, какова задача то?

Узнать, какой тип сгенерировал макрос new. А потом действовать по плану, что я описал в оп-посте.
Re[3]: Почему не удается типизировать?
От: STDray http://stdray.livejournal.com
Дата: 18.10.12 23:12
Оценка:
VD>Честно говоря все это через левое ухо сделано. Типизировать тело можно только специально созданным для этого тайпером.

Переписал DoTransform
Message.Hint("start typing");
def methodTyper = Typer(typeBuilder, null, method, method.Env);
methodTyper.RunFullTyping();
Message.Hint($"$(method.BodyTyped.Type)");
Message.Hint("end typing");

не помогло.
Точнее, если если в теле метода макрос new не используется, то все нормально.
А если используется, то любая попытка типизировать тело, кроме TryTyping, ломает его работу.
Re[4]: Почему не удается типизировать?
От: STDray http://stdray.livejournal.com
Дата: 07.11.12 13:11
Оценка:
STD>Точнее, если если в теле метода макрос new не используется, то все нормально.
STD>А если используется, то любая попытка типизировать тело, кроме TryTyping, ломает его работу.

Ну подскажите хоть в какую сторону смотреть. Начинать дебажить конпелятор, да?
Re[4]: Почему не удается типизировать?
От: ionoy Эстония www.ammyui.com
Дата: 07.11.12 14:00
Оценка:
Здравствуйте, STDray, Вы писали:

STD>Точнее, если если в теле метода макрос new не используется, то все нормально.


А что за ошибка хоть?
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.