public class ZList[T] : SCG.IList.[T]
DB value_ : SCG.List.[T]
в котором макрос DB генерирует код в зависимости от точного типа value_. существует способ отложить его работу или
как то перенаправить в отложенную процедуру до подстановки(там где юзер определит T для ZList)? т. к. в контексте обобщенного типа вызов макроса для меня не имеет смысла.
Здравствуйте, _Claus_, Вы писали:
_C_>в котором макрос DB генерирует код в зависимости от точного типа value_. существует способ отложить его работу или _C_>как то перенаправить в отложенную процедуру до подстановки(там где юзер определит T для ZList)? т. к. в контексте обобщенного типа вызов макроса для меня не имеет смысла.
Здравствуйте, _Claus_, Вы писали:
_C_>в котором макрос DB генерирует код в зависимости от точного типа value_. существует способ отложить его работу или _C_>как то перенаправить в отложенную процедуру до подстановки(там где юзер определит T для ZList)? т. к. в контексте обобщенного типа вызов макроса для меня не имеет смысла.
Мы подумываем о разработке макросов-расширений. Это макросы которые выглядят как методы расширени, но по факту являются некой помисью шаблоных функций С++ и макросов.
Вот в них будет возможность сделать что-то похожее на то что ты хочешь. В коде они будут выглядеть как обычный вызов, например так:
lst.Map(x => SomeCall(x));
но в реальности вместо вызова будет раскрываться макрос.
От обычных макросов макросы-расширения отличаются тем, что они описываю типы своих параметров (как методы) и выбор между ними будет производиться на основе штатного алгоритма разрешения перегрузки. Таким образом макрос получит не только АСТ которое было подставлено в качестве параметров, но и типы которые вывелись для этого АСТ.
Вот это будут конкретные типы. Их можно будет читать и генерировать специализированные версии.
Приведенный ниже пример — не более чем общая идея. Детали могут сильно измениться. Этот пример демонстрирует гипотетическую реализацию макроса-расширения Map, который заменит аналогичную функцию:
macro method Map[Collection[_], T1, T2](this source : Collection[T1], func : T1 -> T2) : Collection[T2]
{
...
if (Collection.IsArray) // Проверка типа коллекции. Здесь Collection - это TypeInfo
<[ // Реализация для массиваdef source = $source;
def newArray = array(source.Length);
foreach (elem in source with i)
newArray[i] = func(elem);
newArray
]>
else if (Collection.Equals(typer.InternalType.List)) // еще одна проверка типа коллекции
<[
Реализация для списка
]>
else
<[
Реализация общего случая
]>
}
В и тоге мы имеем аналог функций поддерживающих полиморфизм второго (а то и высших) порядка. При этом не имея тех проблем которые с ними связаны. Полиморфизм второго позволит иметь тип возвращаемого значения таких "методов" таким же каков была входная коллекция. Так если применить это дело к массиву, то на выходе будет массив. А если применить к списку, то список.
Кода подставляется по месту. Это приводит к инлайнингу функции func и очень эффективному коду.
Минус — макросы-расширения нельзя использовать как функции высших порядков (передавать в качестве параметра, помещать в массив).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
_C_>>в котором макрос DB генерирует код в зависимости от точного типа value_. существует способ отложить его работу или _C_>>как то перенаправить в отложенную процедуру до подстановки(там где юзер определит T для ZList)? т. к. в контексте обобщенного типа вызов макроса для меня не имеет смысла.
VD>Мы подумываем о разработке макросов-расширений. Это макросы которые выглядят как методы расширени, но по факту являются некой помисью шаблоных функций С++ и макросов.
Насколько я понял, Claus'a не интересует тип коллекции, а интересует тип элемента. В некоторых частных случаях его можно вывести, но что делать при вызове макроса с обобщенным типом?
f(this x : List[T]) : List[T]
{
x.someMacroExt() // здесь компилятор никак не узнает тип T
}
Re[2]: макрос времени подстановки типа
От:
Аноним
Дата:
27.01.12 06:15
Оценка:
VD>Минус — макросы-расширения нельзя использовать как функции высших порядков (передавать в качестве параметра, помещать в массив).
Здравствуйте, Аноним, Вы писали:
VD>>Минус — макросы-расширения нельзя использовать как функции высших порядков (передавать в качестве параметра, помещать в массив).
А>Этот минус обязателен?
Ну, а как иначе? Макрос — это сущность времени компиляции. Он не вызывается, а раскрывается. Такой макрос можно будет передавать в качестве замены функции в другие такие же макросы, но передать в фунцию его неудастся. Пред этим его придется материализовать и превратить в обычный метод. В таком виде его можно будет использовать как ФВП. Но преобразование в функцию будет произведено еще при передаче. И особого эффекта от этого не будет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: макрос времени подстановки типа
От:
Аноним
Дата:
27.01.12 07:01
Оценка:
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Аноним, Вы писали:
VD>>>Минус — макросы-расширения нельзя использовать как функции высших порядков (передавать в качестве параметра, помещать в массив).
А>>Этот минус обязателен?
VD>Ну, а как иначе? Макрос — это сущность времени компиляции. Он не вызывается, а раскрывается. Такой макрос можно будет передавать в качестве замены функции в другие такие же макросы, но передать в фунцию его неудастся. Пред этим его придется материализовать и превратить в обычный метод. В таком виде его можно будет использовать как ФВП. Но преобразование в функцию будет произведено еще при передаче. И особого эффекта от этого не будет.
Главное что бы при написании кода не пришлось различать что передалось функция или макрометод....
Здравствуйте, Аноним, Вы писали:
А>Главное что бы при написании кода не пришлось различать что передалось функция или макрометод....
Обеспечить незаметное преобразование макроса-расширения (макро-метод, тоже не плохо, кстати) в ссылку на функцию — думаю будет не сложно. Но естественно после этого все вкусности макроса будут утрачены, а тип функции фиксирован типом аргумента в который передается макро-метод.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: макрос времени подстановки типа
От:
Аноним
Дата:
27.01.12 13:34
Оценка:
Здравствуйте, VladD2, Вы писали:
VD>Обеспечить незаметное преобразование макроса-расширения (макро-метод, тоже не плохо, кстати) в ссылку на функцию — думаю будет не сложно. Но естественно после этого все вкусности макроса будут утрачены, а тип функции фиксирован типом аргумента в который передается макро-метод.
Если реализовать зависимые типы то может работать на любом этапе, правда пока не ясны не одного случая когда это имеет смысл в программировании интерфейса и т д...
Здравствуйте, VladD2, Вы писали:
VD>Мы подумываем о разработке макросов-расширений. Это макросы которые выглядят как методы расширени, но по факту являются некой помисью шаблоных функций С++ и макросов.
VD>Вот в них будет возможность сделать что-то похожее на то что ты хочешь. В коде они будут выглядеть как обычный вызов, например так: VD>
VD>lst.Map(x => SomeCall(x));
VD>
VD>но в реальности вместо вызова будет раскрываться макрос.
Может ли это решить задачу _Claus_, если нужно просто вызвать макрос, а не делать раскрытие макроса-метода расширения, те как показал он:
public class ZList[T] : SCG.IList.[T]
DB value_ : SCG.List.[T]
Здравствуйте, CodingUnit, Вы писали:
CU>Может ли это решить задачу _Claus_, если нужно просто вызвать макрос, а не делать раскрытие макроса-метода расширения, те как показал он:
CU>
CU>public class ZList[T] : SCG.IList.[T]
CU> DB value_ : SCG.List.[T]
CU>
CU>Как в DB можно будет узнать тип T?
Очевидно, что в дженериках это не будет работать. Но вместо дженериков ведь можно использовать макросы. При работе с БД всегда есть конкретный набор типов. Вот с ним эти макросы будут вычислять конкретный тип.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
CU>>public class ZList[T] : SCG.IList.[T]
CU>> DB value_ : SCG.List.[T]
CU>>
VD>Очевидно, что в дженериках это не будет работать. Но вместо дженериков ведь можно использовать макросы. При работе с БД всегда есть конкретный набор типов. Вот с ним эти макросы будут вычислять конкретный тип.
Если такая потребность не уникальна и может пригодиться в других местах, то решить ее можно путем маркировки класса, как "вычисляемого".
Такой класс не будет раскрываться до тех пор, пока не получит все нужные параметры. и компилятор (или спец макрос) разворачивает его в обычный класс
в момент подстановки конкретных типов. и все макросы видят конкретику.
к стати вот это с traits до релиза дошло? вижу с этим общий функционал.
Здравствуйте, _Claus_, Вы писали:
_C_>Если такая потребность не уникальна и может пригодиться в других местах, то решить ее можно путем маркировки класса, как "вычисляемого". _C_>Такой класс не будет раскрываться до тех пор,...
Дженерики поддерживаются рантаймом дотнета и моно. Так что влиять на них мы не можем.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, _Claus_, Вы писали:
_C_>Такой класс не будет раскрываться до тех пор, пока не получит все нужные параметры. и компилятор (или спец макрос) разворачивает его в обычный класс _C_>в момент подстановки конкретных типов. и все макросы видят конкретику.
Это называется шаблоны С++. Подход сугубо не рантаймный.
_C_>к стати вот это с traits до релиза дошло? вижу с этим общий функционал.
Нет. Особой необходимости не было. И это из другой серии.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>Это называется шаблоны С++. Подход сугубо не рантаймный.
Да и хорошо, что не рантаймный. Мне и нужно во время компиляции все порешать.
_C_>>к стати вот это с traits до релиза дошло? вижу с этим общий функционал.
VD>Нет. Особой необходимости не было. И это из другой серии.
Функционал traits возрос бы, если можно было бы анализировать и условно строить код по типам, даже когда они описаны как generic параметры.
Теоретически, есть препятствия для такого перехвата, кроме выпадения для макросов фазы BeforeInheritance?
Здравствуйте, _Claus_, Вы писали:
_C_>Функционал traits возрос бы, если можно было бы анализировать и условно строить код по типам, даже когда они описаны как generic параметры.
Еще раз повторяю, что трэйтсы из другой серии. Они на системе типов дотнета основаны. Ты же говоришь о шаблонах. Шаблоны при наличии дженериков и макросов — это изращение. Тебе просто надо научиться использовать имеющиеся возможности.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, _Claus_, Вы писали:
_C_>>Такой класс не будет раскрываться до тех пор, пока не получит все нужные параметры. и компилятор (или спец макрос) разворачивает его в обычный класс _C_>>в момент подстановки конкретных типов. и все макросы видят конкретику.
VD>Это называется шаблоны С++. Подход сугубо не рантаймный.
Мне почему то пришло в голову, что возможно было бы интересно на Н сделать аналог шаблонов С++, то есть что то типа генериков, но которые связываются не в рантайме, типа макроса template, как то так:
[template(T)]
class Test
{
}
функционирование их должно быть как у шаблонов, для этого потребуется только наверное немалая работа, надо будет делать что то типа инстанционирования шаблонов, но думаю это возможно, насколько это целесообразно?