Реализация шаблонов на макросах
От: CodingUnit Россия  
Дата: 05.02.12 20:55
Оценка:
Как мы уже говорили стоит задача в макросах получать значение типа обобщенного параметра. Я подумал и придумал первое простое решение этого:

Здесь в коде ниже DB это макрос куда надо передать обобщенный параметр.
Существует два макроса template и instance может быть со своим синтаксисом, пока над синтаксисом не думал и оставил так:


[template(T)]
class Test
{
  inst(DB(T)) value : List[T];
}

// и где то
def test = inst(Test, int)(); // то есть инстанционируем шаблон


Далее можно сделать вот что, макрос inst должен найти определение класса Test и запустить его инстанционирование, для параметра int создать копию Test в том же пространстве, попутно надо просканировать его члены, все обращения к T должны заменяться на параметр int и получится такая же копия Test только с известным параметром int.

во что должен быть преобразован код:


class Test_int
{
  DB(int) value : List[int];
}

// и в месте инстанционирования
def test = Test_int(); // в конечный код подставляется уже Test_int


Сам макрос inst должен понимать что он собирается инстанционировать если это макрос то он должен откладываться до известного параметра, который будет подставлять только запуск inst для шаблонного класса. Макросы template и inst из конечного класса удаляются, заместо inst подставляется выражение которое он инстанционирует если параметр известен. Макрос DB тоже просто с параметром T лучше не оставлять в коде класса потому что он будет раскрыт с этим выражением, поэтому делается inst(DB(T)). Хотя синтаксис можно придумать для этого, и все это как мне кажется не требует никакой переделки компилятора.

Какие мысли по этому поводу?
Re: Реализация шаблонов на макросах
От: _Claus_  
Дата: 05.02.12 21:35
Оценка:
CU>Какие мысли по этому поводу?

Мою предложение — вычислимым типам быть с имеющимся синтаксисом описания и использования.
для однородности.

вместо

[template(T)]
class Test
{
  inst(DB(T)) value : List[T];
}

// и где то
def test = inst(Test, int)(); // то есть инстанционируем шаблон


писать


macroclass Test[T]
{
  DB value : List[T];
}

macrostruct CT[T]
{
  val : List[T];
}


// и где то
def test = Test[int](); // то есть инстанционируем шаблон


Эти macroclass и macrostruct должны разворачиваться в начале фазы BeforeInheritance, до вызова всех остальных кастомных макросов.
Re[2]: Реализация шаблонов на макросах
От: _Claus_  
Дата: 05.02.12 21:45
Оценка:
если macroclass можно разбить на macro class, т. е.


macro class Test[T]
{
  value : List[T];
}


было бы лучше, но есть мнение (не мое), что отдельным словом сделать проще — сложности меньше.
Re: Реализация шаблонов на макросах
От: catbert  
Дата: 05.02.12 22:26
Оценка:
Еще тогда про инты и стринги в шаблонах не забудьте.
Re[2]: Реализация шаблонов на макросах
От: _Claus_  
Дата: 05.02.12 22:41
Оценка:
Здравствуйте, catbert, Вы писали:

C>Еще тогда про инты и стринги в шаблонах не забудьте.


конечно шаблон предполагает любое допустимое описание класса/структуры.
вместе со вложенными макросами, макросами на класс и пр. все как обычно.
Re[2]: Реализация шаблонов на макросах
От: CodingUnit Россия  
Дата: 06.02.12 06:12
Оценка:
Здравствуйте, _Claus_, Вы писали:


_C_>писать



_C_>
_C_>macroclass Test[T]
_C_>{
_C_>  DB value : List[T];
_C_>}

_C_>macrostruct CT[T]
_C_>{
_C_>  val : List[T];
_C_>}


_C_>// и где то
_C_>def test = Test[int](); // то есть инстанционируем шаблон
_C_>


_C_>Эти macroclass и macrostruct должны разворачиваться в начале фазы BeforeInheritance, до вызова всех остальных кастомных макросов.


macroclass не могут разворачиваться вообще, потому что они не знают какие должны потребоваться типы параметров для генерации классов. Если бы можно было раскрыть сначала все inst в телах методов, тогда можно было бы сохранить список нужных типов где то, но сейчас это наверное невозможно, поскольку раскрытие в телах методов происходит после раскрытия макросов аттрибутов. Поэтому template ничего не должен делать, только хранить информацию как аттрибут. Всю работу будет производить inst в теле метода.
Тут несколько конфликтов, во первых вводить пока новый синтаксис macroclass расточительно, зачем нам новый тип класса, аттрибут template пока решает задачу, вводить новый синтаксис надо оставить на потом, это самая сложная переделка компилятора и меняет всю его концепцию. Макрос template пока ничего нового не привносит и решает свою задачу, идею надо сначала проверить. Тоже и Test[int] внутри метода, он совпадает с синтаксисом генериков, это тоже немалая переделка, в этом месте и должно производиться раскрытие макроса и вся работа по инстанционированию, возможно если идея будет принята окончательно, то для этого можно будет задействовать синтаксис сходный с генериками, пока еще все сообщество не приняло шаблонов в язык и это не должно каснуться никого, поэтому обычный макрос с расширением синтаксиса будет лучшее решение. Если он будет решать свои задачи этого пока будет достаточно, еще неизвестно какие могут встать проблемы при разработке и использовании макроса, поэтому пока оставим такой вариант.
Я еще подумал что могут быть проблемы с использованием этих классов из других сборок, инстанционировать их там надо тоже через inst, но макрос при этом будет смотреть в текущем проекте этот класс если не найдет он просто пропускает работу и генерирует на выходе имя какое создается по соглашению для инстанций шаблонных классов, если класс с таким именем будет открыт в пространстве, то он подцепится и будет в коде использован правильно.
То есть окончательно шаблон в этой реализации не более чем такой же класс но с подставленным типом параметра и своим именем, и связывается во время компиляции а не во время исполнения как генерики. Еще мысли?
Re[3]: Реализация шаблонов на макросах
От: _Claus_  
Дата: 06.02.12 11:46
Оценка:
CU>macroclass не могут разворачиваться вообще, потому что они не знают какие должны потребоваться типы параметров для генерации классов. Если бы можно было раскрыть сначала все inst в телах методов, тогда можно было бы сохранить список нужных типов где то, но сейчас это наверное невозможно, поскольку раскрытие в телах методов происходит после раскрытия макросов аттрибутов. Поэтому template ничего не должен делать, только хранить информацию как аттрибут. Всю работу будет производить inst в теле метода.

в предлагаемом мной варианте он разворачивается для каждого найденного расширения — определения. Это возможно в начале этапа BeforeInheritance.

В компиляторе должна быть добавлена новая сущность macrotype. Которая будет 1 в 1 класс, только с дополнительной фазой обработки-коррекции.


CU>Тут несколько конфликтов, во первых вводить пока новый синтаксис macroclass расточительно, зачем нам новый тип класса, аттрибут template пока решает задачу, вводить новый синтаксис надо оставить на потом, это самая сложная переделка компилятора и меняет всю его концепцию.


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

CU> Макрос template пока ничего нового не привносит и решает свою задачу, идею надо сначала проверить.


Я в своем предложении логических проблем не вижу. Но вот если макросом — это сомнительная фича, вносящая больше вопросов, чем ответов.
CU> Я еще подумал что могут быть проблемы с использованием этих классов из других сборок, инстанционировать их там надо тоже через inst, но макрос при этом будет смотреть.

вот читаешь прям мои мысли. мне бы хотелось видеть в отладчике имя класса c такой нотацией X'1'int , а в сборке ничего другого как
X_1_int не получится, ибо соглашения .Net.


CU> То есть окончательно шаблон в этой реализации не более чем такой же класс но с подставленным типом параметра и своим именем, и связывается во время компиляции а не во время исполнения как генерики. Еще мысли?


Тип параметра еще int и string. string может быть (и надеюсь будет) использован в качестве параметра для вложенных макросов.
Re[4]: Реализация шаблонов на макросах
От: CodingUnit Россия  
Дата: 06.02.12 16:16
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>в предлагаемом мной варианте он разворачивается для каждого найденного расширения — определения. Это возможно в начале этапа BeforeInheritance.


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

_C_>В компиляторе должна быть добавлена новая сущность macrotype. Которая будет 1 в 1 класс, только с дополнительной фазой обработки-коррекции.


Два раза типизировать тела методов на это мы пойти не можем

_C_>Разумеется, если бы можно было обойтись одними макросами — вопрос бы не стоял. Но вложенные макросы требуют, чтобы их работа не была нарушена или

_C_>изменена новшеством. для моей задачи это категорически важно. Поэтому для вложенных макросов, даже тех, которые работают на BeforeInheritance, должна быть обеспечена прозрачность доступа
_C_>к типам, независимо от того, внутри макротипа они, или обычного класса.

Можно обойтись и макросами, внутренние макросы ничего не будут знать во время своего раскрытия, в шаблонном классе они не раскрываются потому что находятся в выражении внешнего макроса inst который их там не раскрывает, а вставляет в конечный класс — инстанцию, в котором они будут раскрыты в порядке очереди

_C_>Я в своем предложении логических проблем не вижу. Но вот если макросом — это сомнительная фича, вносящая больше вопросов, чем ответов.


Логически не видишь потому что не представляешь что можно будет сделать с компилятором, а я вижу большие переделки, и их можно избежать одними макросами. Это возможно, поскольку макросы уровня выражения могут добавлять новые классы в пространство имен, и искать те или иные определения в текущем проекте

_C_>Тип параметра еще int и string. string может быть (и надеюсь будет) использован в качестве параметра для вложенных макросов.


На типы параметров ограничений нет, они могут быть любыми, как выражения параметров макросов
Re[5]: Реализация шаблонов на макросах
От: _Claus_  
Дата: 06.02.12 17:55
Оценка:
Здравствуйте, CodingUnit, Вы писали:

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


_C_>>в предлагаемом мной варианте он разворачивается для каждого найденного расширения — определения. Это возможно в начале этапа BeforeInheritance.


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


На этапе BeforeInheritance в выражениях PExpr, описывающих члены, я вижу типы. для методов тоже видно, что за тип описан, пусть и представление другое.
Вижу все, что мне надо.
В этом месте компилятор имеет описание возвращаемого типа (расширенного) в виде PExpr,
самого макротипа в виде TypeBuilder, и таки да, можно сгенерировать новый тип с этими, уже видимыми параметрами и подставить сгенеренное имя типа. Но это умозрительно. это нарушает наверняка какие-то каноны, но вполне возможно. ну в голове по крайней мере.

CU>Можно обойтись и макросами, внутренние макросы ничего не будут знать во время своего раскрытия, в шаблонном классе они не раскрываются потому что находятся в выражении внешнего макроса inst который их там не раскрывает, а вставляет в конечный класс — инстанцию, в котором они будут раскрыты в порядке очереди


я вижу проблему — прицепленные к макротипу макросы этапа BeforeInheritance. как внутренние, так и уровня класса. как ты обеспечишь их нужный приоритет,
без поддержки компилятора?

Как писать тип, когда он завязан на возврат макроса? Некрасиво получится — общество отвергнет. Давай попробуем учесть все моменты.

_C_>>Я в своем предложении логических проблем не вижу. Но вот если макросом — это сомнительная фича, вносящая больше вопросов, чем ответов.


CU>Логически не видишь потому что не представляешь что можно будет сделать с компилятором, а я вижу большие переделки, и их можно избежать одними макросами. Это возможно, поскольку макросы уровня выражения могут добавлять новые классы в пространство имен, и искать те или иные определения в текущем проекте


очень удобно было бы, если вся машинерия будет спрятана под капот.
сильно сомневаюсь что макросами можно достойно порешать, но если ты уверен — дайда бог.
Re[6]: Реализация шаблонов на макросах
От: CodingUnit Россия  
Дата: 06.02.12 18:18
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>На этапе BeforeInheritance в выражениях PExpr, описывающих члены, я вижу типы. для методов тоже видно, что за тип описан, пусть и представление другое.


На фазе BeforeInheritance в template(T) будет только T и ничего другого, также и во вложенном макросе, они раскрываются до раскрытия макросов в телах методов уровня выражения и их результат должен быть просто проигнорирован потому что тип T еще неизвестен

_C_> В этом месте компилятор имеет описание возвращаемого типа (расширенного) в виде PExpr,

_C_>самого макротипа в виде TypeBuilder, и таки да, можно сгенерировать новый тип с этими, уже видимыми параметрами и подставить сгенеренное имя типа. Но это умозрительно. это нарушает наверняка какие-то каноны, но вполне возможно. ну в голове по крайней мере.

Компилятор не видит этих типов, для него только T, потому что до этого не сделано никакой проверки и нет связи с макросами внутри тел методов,

_C_>я вижу проблему — прицепленные к макротипу макросы этапа BeforeInheritance. как внутренние, так и уровня класса. как ты обеспечишь их нужный приоритет,

_C_>без поддержки компилятора?

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

_C_>Как писать тип, когда он завязан на возврат макроса? Некрасиво получится — общество отвергнет. Давай попробуем учесть все моменты.


писать просто через макрос, а макрос возвращает условное имя, которое знает, поэтому вся работа будет производится над корректным сгенерированным типом, пусть будет некрасиво, эти лишь прототип, никто пока не хочет красоты, главное чтобы идея работала, а отполировать можно уже потом, это не так важно

_C_>очень удобно было бы, если вся машинерия будет спрятана под капот.

_C_>сильно сомневаюсь что макросами можно достойно порешать, но если ты уверен — дайда бог.

можно решить, и вся машинерия будет скрыта, просто надо уметь будет использовать эти типы, получится два разных класса,
один Test помеченный макросом template, и его инстанции для типов, Test_int, Test_string и так далее, надо это не забыть и не делать с Test ничего особого, без известных параметров типов, определяемых через inst
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.