Re[7]: Требуются примеры макросов уровня выражения создающих
От: Ziaw Россия  
Дата: 04.01.11 14:56
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Что-то у них совсем уродское ГУИ. Напоминает ГУЙ к древнему CVS. Почему они просто не содрали ГУЙ с Тортилы для SVN (с учетом особенностей, конечно)?

VD>Ладно. Вопрос риторический .

А какой там гуй глобально отличается? Вобщем-то они все и содрали. Только потом еще сделали одно большое окно в котором можно делать все не вылезая из него. Мне удобно

Тортила для свн она постарше будет, и работает только в винде, с гуем у нее по любому будет получше.
Re[5]: Требуются примеры макросов уровня выражения создающих
От: Аноним  
Дата: 04.01.11 21:34
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Код макроса потенциально может вызывать черте что и находиться вообще в других сборках.

Разве с этим не придется тоже как-то справляться в рамках борьбы за распараллеливание?
Или почему-то будет достаточно только запрета на изменение AST?
Re[6]: Требуются примеры макросов уровня выражения создающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.01.11 00:02
Оценка:
Здравствуйте, Аноним, Вы писали:

H>>Код макроса потенциально может вызывать черте что и находиться вообще в других сборках.

А>Разве с этим не придется тоже как-то справляться в рамках борьбы за распараллеливание?
А>Или почему-то будет достаточно только запрета на изменение AST?

АСТ меняется локально, так что с этим проблем нет. Вот дерево типов вещь глобальная по своей природе. И его изменение (т.е. изменение состава типов и их содержимого) и требует защиты.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Требуются примеры макросов уровня выражения создающих ти
От: Ziaw Россия  
Дата: 05.01.11 07:37
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Мы тут продумываем новую стратегию компиляции. Главной ее особенностью будет параллелизм компиляции тел методов (и вообще, любой макрос может быть запущен параллельно другим. Таким образом мы хотим ввести неизменяемое АСТ которое можно будет только порождать и хотим сделать так чтобы макросы не могли бесконтрольно менять дерево типов и сами типы.


Тут подумалось, что кроме одновременного запуска на нескольких ядрах, это ведь даст возможность запоминать иммутабельные куски и перекомпилировать только измененные части большого проекта. Фактические это означает, что любой корректный код можно запустить в доли секунды.
Re[2]: Требуются примеры макросов уровня выражения создающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.01.11 00:48
Оценка:
Здравствуйте, Ziaw, Вы писали:

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


Собственно неизменяемость добавляется не только из соображений распараллеливания. В частности это упростит разработку поддержки IDE.
Что же касается быстрой компиляции, то там не все так просто. Так что навряд ли удастся сделать инкрементальную компиляцию. Но несомненно неизменяемое АСТ упростит реализацию этой фичи.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Требуются примеры макросов уровня выражения создающих
От: Ziaw Россия  
Дата: 06.01.11 05:56
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Собственно неизменяемость добавляется не только из соображений распараллеливания. В частности это упростит разработку поддержки IDE.

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

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

Например макрос уровня выражения, для запоминания локализованных строк не использует какое то хранилище внутри себя, а просто вставляет кое-то свое UserInfo в AST. При генерации хелперного типа мы сможем получить все свои вшитые UserInfo и сгенерировать нужные поля в каком-то классе.
Re[4]: Требуются примеры макросов уровня выражения создающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.01.11 06:16
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Ну как минимум, результаты парсинга уже можно кешировать. Если


Да. Но не целиком, а по файлам. Изменяющийся файл придется перепарсивать.

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


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

Самое кэширование — это уже императивный подход.

В компиляторе есть структуры данных которые принципиально не могут быть функциональными. Главная из них — это дерево типов. Его части могут быть "чистыми". Но само дерево одно на проект. И как не крути его придется менять. Даже если сделать самое дерево неизменяемым (порождающим новую версию), то все равно будет одна переменная в которую придется поместит новую версию дерева. К тому же хэш-таблицы при больших объемах значительно быстрее нежели деревья. Так что для поиска данных выгоднее использовать хэш-таблицы, а не деревья.
Ну, а к дереву типов нужен параллельный (конкурентный) доступ.

Так что как не крути, а тут без синхронизации не обойтись.

Во-вторых, как я уже говорил есть ряд проблем.

В идеале было бы вообще сделать так, чтобы IDE работала как часть компилятора. Тогда бы можно было вообще почти молниеносно стартовать при изменении тела метода. Но тут вступают в силу реалии мира. Многие макросы настолько медленны, что они по разному работают в режиме IDE и в режиме компиляции. Пример такого макроса — PegGrammar.

Z>Например макрос уровня выражения, для запоминания локализованных строк не использует какое то хранилище внутри себя, а просто вставляет кое-то свое UserInfo в AST. При генерации хелперного типа мы сможем получить все свои вшитые UserInfo и сгенерировать нужные поля в каком-то классе.


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

Потом компилятор ведь не будет знать, что делать с этим UserInfo. Где-то все равно будет код который будет заменять эти UserInfo на код по которому можно сгенерировать выполнимый код. А его результаты уже кэшировать невозможно. Точнее может и можно, но анализ нужно ли это делать или нет будет сложнее генерации.

В общем, есть ряд проблем:
1. Макросы генерирующие типы препятствуют кэшированию.
2. Любое изменение дерева типов приводит к перегенерации всего. Можно попытаться оптимизировать это, но при этом получится очень сложный код.
3. Некоторые макросы принципиально не могут работать быстро. Это приводит к тому, что их поведение в режиме IDE и режиме компиляции отличается. А это не позволяет использовать кэш IDE для компиляции. Выходит, что придется иметь два кэша, но это может оказаться слишком накладно (процессоров то пока что ограниченное количество).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Требуются примеры макросов уровня выражения создающих
От: Ziaw Россия  
Дата: 06.01.11 07:53
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>В компиляторе есть структуры данных которые принципиально не могут быть функциональными. Главная из них — это дерево типов. Его части могут быть "чистыми". Но само дерево одно на проект. И как не крути его придется менять. Даже если сделать самое дерево неизменяемым (порождающим новую версию), то все равно будет одна переменная в которую придется поместит новую версию дерева. К тому же хэш-таблицы при больших объемах значительно быстрее нежели деревья. Так что для поиска данных выгоднее использовать хэш-таблицы, а не деревья.

VD>Ну, а к дереву типов нужен параллельный (конкурентный) доступ.

Хештаблицы вполне могут просто обеспечивать быстрый доступ к листьям дерева и никак не мешают самому существованию дерева, строится оно не медленнее хештаблиц.

А вот требование к мутабельности самого дерева во всех стадиях компиляции действительно сильно напрягает. Может подумать в сторону нескольких этапов трансформаций дерева типов? Тогда мы сможем иметь дело с иммутабельным lock-free деревом типов.

Правда макрос придется писать либо в event-driven виде, либо cps, либо как сейчас: несколько одноименных макросов на разные стадии компиляции. Стадии компиляции, все равно придется синхронизировать, от этого не уйти, зато очередную трансформацию дерева можно запускать как только мы получили все нужные для нее данные, что дает хорошее поле для оптимизаций порядка запуска макросов.
Re[6]: Требуются примеры макросов уровня выражения создающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.01.11 08:55
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Хештаблицы вполне могут просто обеспечивать быстрый доступ к листьям дерева и никак не мешают самому существованию дерева, строится оно не медленнее хештаблиц.


Гы. Хэш-таблицы — это императивные штуки. Их нужно синхронизировать. По сему проще запретить менять дерево напрямую.

Z>А вот требование к мутабельности самого дерева во всех стадиях компиляции действительно сильно напрягает. Может подумать в сторону нескольких этапов трансформаций дерева типов? Тогда мы сможем иметь дело с иммутабельным lock-free деревом типов.


Об этом я и думаю. Вольфхаунд предлагает как ты (в первый раз) не парясь тупо возвращать новые типы из макросов и потом их сувать в дерево (не парясь над конфликтами). Но это сильно усложнит жизнь марописателям.

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

Z>Правда макрос придется писать либо в event-driven виде, либо cps, либо как сейчас: несколько одноименных макросов на разные стадии компиляции. Стадии компиляции, все равно придется синхронизировать, от этого не уйти, зато очередную трансформацию дерева можно запускать как только мы получили все нужные для нее данные, что дает хорошее поле для оптимизаций порядка запуска макросов.


Ага. Тут есть над чем подумать. Мне больше нравятся варианты с cps и запросом на создание/модификацию типа. В последнем случае можно попытаться автоматически вычислить, что ссылка идет на еще не добавленный тип и автоматом отложить типизацию на следующую стадию. А стадии сделать неограниченными.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Требуются примеры макросов уровня выражения создающих
От: Ziaw Россия  
Дата: 06.01.11 14:36
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Гы. Хэш-таблицы — это императивные штуки. Их нужно синхронизировать. По сему проще запретить менять дерево напрямую.


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

Z>>А вот требование к мутабельности самого дерева во всех стадиях компиляции действительно сильно напрягает. Может подумать в сторону нескольких этапов трансформаций дерева типов? Тогда мы сможем иметь дело с иммутабельным lock-free деревом типов.


VD>Об этом я и думаю. Вольфхаунд предлагает как ты (в первый раз) не парясь тупо возвращать новые типы из макросов и потом их сувать в дерево (не парясь над конфликтами). Но это сильно усложнит жизнь марописателям.


Я предлагал не это, я предлагал выделить задачи по изменению типов в отдельную стадию и исполнять их синхронно в одном потоке. UserInfo в AST предлагалось как альтернатива сбору инфы для генерации типа в статическую переменную в других стадиях. Т.е. макрос всегда имеет дерево на входе и дерево на выходе.

Допустим трансформируем мы
unless (macro1(x))
{
  macro2();
  macro3();
}


Макрос unless возвращает не до конца вычисленный матч,
match (macro1(x))
{
  | false => 
    macro2();
    macro3()
  | true => 
    ()
}

в котором еще не успели вычислиться выражения макросов, но уже известно, что это матч с двумя отложенными вычислениями. Если бы макросу unless захотелось создать или изменить тип — он прикрепил бы метаинформацию требуемую для конструирования типа в UserInfo этого же матча. Сейчас это инфа кладется в различные статические по отношению к макросу переменные, соответственно макрос имеет сайд эффекты, мы не можем его отложить его вызов на сколько угодно и не можем вызвать дважды. Вопрос по структурам обеспечивающим быстрый доступ к этой инфе оставляю пока открытым.

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


Вероятно у него есть какой-то не до конца созревший план.

VD>Ага. Тут есть над чем подумать. Мне больше нравятся варианты с cps и запросом на создание/модификацию типа. В последнем случае можно попытаться автоматически вычислить, что ссылка идет на еще не добавленный тип и автоматом отложить типизацию на следующую стадию. А стадии сделать неограниченными.


Именно, стадий должно быть столько сколько нужно коду. Тут правда встает вопрос о неаккуратном замедлении компиляции и сложностью выявления таких мест, но это тоже решаемый момент.
Re[5]: Требуются примеры макросов уровня выражения создающих
От: WolfHound  
Дата: 06.01.11 19:10
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Самое кэширование — это уже императивный подход.

Нет это реактивный подход.

VD>В компиляторе есть структуры данных которые принципиально не могут быть функциональными. Главная из них — это дерево типов. Его части могут быть "чистыми". Но само дерево одно на проект. И как не крути его придется менять. Даже если сделать самое дерево неизменяемым (порождающим новую версию), то все равно будет одна переменная в которую придется поместит новую версию дерева.

И как же в хаскеле fold то работает...

VD>К тому же хэш-таблицы при больших объемах значительно быстрее нежели деревья. Так что для поиска данных выгоднее использовать хэш-таблицы, а не деревья.

Тут не факт что все так просто.
Ибо хештаблици придется постоянно перестраивать, а деревья можно обновлять инкрементально.

VD>Ну, а к дереву типов нужен параллельный (конкурентный) доступ.

На чтение.

VD>Так что как не крути, а тут без синхронизации не обойтись.

Если будет синхронизация то можно сразу тушить свет. Работать все будет хуже чем в одном потоке.

VD>В идеале было бы вообще сделать так, чтобы IDE работала как часть компилятора. Тогда бы можно было вообще почти молниеносно стартовать при изменении тела метода. Но тут вступают в силу реалии мира. Многие макросы настолько медленны, что они по разному работают в режиме IDE и в режиме компиляции. Пример такого макроса — PegGrammar.

Это следствие отсутствия стройной концепции стоящей за макросистемой.
Сейчас все навалено в большуюю кучу в которой хрен разберешься.
Поляки делали макро систему примерно также как автор D делал D.
Решения принимались по принципу: "Ой какая фича! Давайте и ее прикрутим!"

На самом деле нам нужно вводить 3 больших этапа трансляции программы.
1)Парсинг.
Идеология этого этипа проста:
Парсер это чистая функция от текста и загруженных в проект синтаксических макросов.
Чистая означает что мы можем как угодно плющить АСТ поступивший в обработчики и все на этом.
Те никаких вызовов внешнего кода. Никакого изменения глобальных переменных итп быть не должно.

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

2)Типизация и генерация видимых пользователю типов и методов.
Не важно приватных или публичных.

3)Кодогенерация.
На этом этапе должн генерироваться тот код который пользователь никогда не увидит.
В случае с тем же PegGrammar это методы семейства __GENERATED_PEG__RULE__*__

В интеграции нам нужны только первые два этапа.

Причем идеологически правильно чтение из всех внешних источников данных делать на первом этапе.
Те если мы хотим прочитать метаданные из базы нужно представить что база это некий виртуальный исходник. Прочитать метаданные и положить их в АСТ.

А всю запись во внешние хранилища производить на третьем этапе.

На втором этапе никаких походов за приделы компилятора быть не должно.

Детали я еще подумаю но каркас компилятора должен быть именно таким.
Иначе у нас не будет шансов сделать понятную систему.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: Требуются примеры макросов уровня выражения создающих
От: Ziaw Россия  
Дата: 06.01.11 20:02
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>2)Типизация и генерация видимых пользователю типов и методов.

WH>Не важно приватных или публичных.

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

Осталось понять как записать макрос, для которого это все должно выглядеть императивно.

// допустим нам нужна макра создающая массив и заполняющая его значениями зависящими от типа элемента.
def x = my_array(5);

when (x[0] == "1") // вот тут по идее компилятор сможет вывести тип из использования
{
 ...
}

macro my_array 
  syntax my_array '(' count : int ')'
{
  // здесь мы должны прервать выполнение макроса и дождаться вывода типов 
  // но парсинг должен продолжаться, поэтому мы, для начала возвращаем заглушку
  def unknownType = Context.MakeUnknownType()
  def knownType = yield <[ array.[$unknownType]($count) ]> and wait Context.GetType(unknownType); 

  // сюда мы попадаем уже после той стадии типизации, которая смогла вывести тип для заглушки
  def defaultValue = GetDefaultExprForType(knownType); // логика получения дефолтного выражения для типа не важна для примера

  <[
    def arr = array($count);
    for (int i = 0; i < arr.Length; i++)
       arr[i] = $defaultValue;
    arr
  ]>  // а вот это уже окончательный вариант работы макроса, генерация кода
}


Этот макрос сам не трогает дерево типов, как только начнет — типизацию придется проводить заново после его выполнения.
Re[6]: Требуются примеры макросов уровня выражения создающих
От: Ziaw Россия  
Дата: 06.01.11 20:15
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Те если мы хотим прочитать метаданные из базы нужно представить что база это некий виртуальный исходник. Прочитать метаданные и положить их в АСТ.


Только эти метаданные в AST надо научиться помечать как не кешируемые. Ибо изменяться они могут чаще чем исходник с макросом который их порождающим.
Re[7]: Требуются примеры макросов уровня выражения создающих
От: WolfHound  
Дата: 06.01.11 20:33
Оценка: 9 (1)
Здравствуйте, Ziaw, Вы писали:

Z>Вот этот этап не совсем ясен, после него, некие синтаксические макры захотят сделать что-то еще.

Синтаксические макры это макры которые текст разбирают. Те это этап номер 1.

Z>Осталось понять как записать макрос, для которого это все должно выглядеть императивно.

А может не надо императивно?

macro MyArray 
"my_array" "(" count : Expression ")"
type of count int;
type of return array[$knownType]; // Говорим что возвращаемое значение должно быть этого типа
{
  def defaultValue = GetDefaultExprForType(knownType);
  <[
    def arr = array($count);
    for (int i = 0; i < arr.Length; i++)
       arr[i] = $defaultValue;
    arr
  ]>
}


На первом этапе у нас отработает только парсер и поместит в АСТ просто разобранный код:
MyArray(IntLiteral(1))
На втором этапе отработает информация о типах.
На третьем этапе уже будет вызван сам код макроса.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: Требуются примеры макросов уровня выражения создающих
От: Ziaw Россия  
Дата: 06.01.11 20:55
Оценка:
Здравствуйте, WolfHound, Вы писали:

Z>>Вот этот этап не совсем ясен, после него, некие синтаксические макры захотят сделать что-то еще.

WH>Синтаксические макры это макры которые текст разбирают. Те это этап номер 1.

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

Z>>Осталось понять как записать макрос, для которого это все должно выглядеть императивно.

WH>А может не надо императивно?

WH>На первом этапе у нас отработает только парсер и поместит в АСТ просто разобранный код:

WH>MyArray(IntLiteral(1))
WH>На втором этапе отработает информация о типах.
WH>На третьем этапе уже будет вызван сам код макроса.

Идея очень нравится. Только не очень понятно, как описать макру возвращающую тип который требуется создать. Конструктор анонимного типа или viewmodel в nrails. До создания этого типа полная типизация невозможна, создание типа до проведения частичной типизации тоже выглядит невозможным.
Re[7]: Требуются примеры макросов уровня выражения создающих
От: WolfHound  
Дата: 06.01.11 21:01
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Только эти метаданные в AST надо научиться помечать как не кешируемые. Ибо изменяться они могут чаще чем исходник с макросом который их порождающим.

Тут нужно делать хитрее.
Нужно сделать "поставщиков АСТ" частным случаем которых будут исходники положенные в проект.
ast provider DataBaseMetadataProvider(connectionString : string) : DataBaseMetadata
load
{//Производит чтение метаданных из базы.
//Возвращает АСТ
}
need update
{//вызывается каждый раз когда компилятор хочет узнать не изменился ли АСТ
//Возвращает true если нужно обновить АСТ.
//Если вернули true то вызывается load
}

Также нужно подумать о том как провайдер может сказать компилятору о том что аст нужно перечитать.

Таким образом мы можем не только перечитывать АСТ чаще чем парсим исходник где вызывается DataBaseMetadataProvider но и реже. Ибо зачем перечитывать базу данных если connectionString не изменился?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: Требуются примеры макросов уровня выражения создающих
От: Ziaw Россия  
Дата: 06.01.11 21:16
Оценка:
Здравствуйте, WolfHound, Вы писали:

Z>>Только эти метаданные в AST надо научиться помечать как не кешируемые. Ибо изменяться они могут чаще чем исходник с макросом который их порождающим.

WH>Тут нужно делать хитрее.
WH>Нужно сделать "поставщиков АСТ" частным случаем которых будут исходники положенные в проект.

У меня тоже последнее время крутятся мысли вокруг фшарповских typeproviders.

WH>Также нужно подумать о том как провайдер может сказать компилятору о том что аст нужно перечитать.


Тут как раз обычный ООП подойдет, задаем у базового класса
public virtual IsModfiedSince(DateTime dt) : bool { true }
и даем возможность провайдеру самому управлять кешированием.

WH>Таким образом мы можем не только перечитывать АСТ чаще чем парсим исходник где вызывается DataBaseMetadataProvider но и реже. Ибо зачем перечитывать базу данных если connectionString не изменился?


Например затем, чтобы прочитать актуальную версию изменившейся схемы или свежие данные. Но основная мысль понятна, IsModfiedSince ей в помощь.
Re[8]: Требуются примеры макросов уровня выражения создающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.01.11 07:07
Оценка: :)
Здравствуйте, WolfHound, Вы писали:

Z>>Осталось понять как записать макрос, для которого это все должно выглядеть императивно.

WH>А может не надо императивно?

WH>
WH>macro MyArray 
WH>"my_array" "(" count : Expression ")"
WH>type of count int;
WH>type of return array[$knownType]; // Говорим что возвращаемое значение должно быть этого типа
WH>{
WH>  def defaultValue = GetDefaultExprForType(knownType);
WH>  <[
WH>    def arr = array($count);
WH>    for (int i = 0; i < arr.Length; i++)
WH>       arr[i] = $defaultValue;
WH>    arr
WH>  ]>
WH>}
WH>


WH>На первом этапе у нас отработает только парсер и поместит в АСТ просто разобранный код:

WH>MyArray(IntLiteral(1))
WH>На втором этапе отработает информация о типах.
WH>На третьем этапе уже будет вызван сам код макроса.

Это какие-то фантазии имеющие мало общего с реальностью и мало понятные. Что такое "type of count int" я так и не понял. Какой-то ОКамл.

В подобных случаях все будет очень просто. Нужно просто применять не один, а два макроса. Один синтаксический, другой обычный. Код будет примерно таким:

macro MyArray 
syntax: "my_array" "(" count : PExpr ")"
{
  <[
    def arr = array($count);

    for (int i = 0; i < arr.Length; i++)
      InitByDefaultValues(arr[i]);
    arr
  ]>
}

macro MakeAssignmentMacro(expr : PExpr)
{
  def typedExpr = typer.TypeExpr(expr);
  def ty = typedExpr.Type.Hint;

  if (ty.HasValue)
    if (ty.Value.Equqlas(typer.StandatrTypes.Int32))
      <[ $typedExpr = 42; ]>
    else if (ty.Value.Equqlas(typer.StandatrTypes.String))
      <[ $typedExpr = "42"; ]>
    else
      PExpr.Error(expr.Location, $"The my_array macro supprt only int and string type, but expression has $(ty.Value) type.")
  else
    null // сообщаем тайперу, что мы пока неготовы раскрыть макрос
}


Скажу больше. Это совершенно надуманный пример, так как для конструкции my_array(3) нет смысла вводить новый синтаксис, так что можно было бы спокойно обойтись обычным макросом.
Более того тут даже макрос был не нужен. Тип для деволтного значения и так не трудно получить. Например, воспользовавшись mutable-переменной не имеющей инициализиатора. Можно даже дженерик-функцию написать:
def my_array[T](count : int)
{
  def arr = array($count);

  for (int i = 0; i < arr.Length; i++)
    arr[i] = default(T);
  arr
}


Если говорить о текущей реализации макросов, то и тут это спокойно реализуется.

ЗЫ

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

Это четко демонстрирует, что все разговоры о концепциях очень быстро разбиваются о реальность, если их не подкреплять скрупулезным (детальным) планом реализации.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Требуются примеры макросов уровня выражения создающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.01.11 10:51
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


Z>>Только эти метаданные в AST надо научиться помечать как не кешируемые. Ибо изменяться они могут чаще чем исходник с макросом который их порождающим.

WH>Тут нужно делать хитрее.
WH>Нужно сделать "поставщиков АСТ" частным случаем которых будут исходники положенные в проект.

Таких поставщиков можно просто оформлять отдельными проектами. Перекомплил проект, получил обновление метаданных. В рамках проекта могут и более сложные макры работать которые могут отслеживать изменения в СУБД хоть по таймеру, хоть как. Ну, и при изменении тупо махать список типов.

В новой версии компилятора проект (или сборка) у нас будет выражаться вот таким интерфейсом:
  public interface IReferencedAssembly
  {
    CustomAttributes  : ICustomAttributes { get; }
    Types             : Seq[NTypeInfo]    { get; }
    Macros            : Seq[IMacro2]      { get; }
    Msgs              : list[Msg]         { get; }
    ImagePath         : string            { get; }
    FullName          : string            { get; }

    event Changed : EventHandler;


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

Получается стройная модель для случаев вроде провайдеров метаданных СУБД.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Требуются примеры макросов уровня выражения создающих
От: WolfHound  
Дата: 07.01.11 13:08
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Таких поставщиков можно просто оформлять отдельными проектами. Перекомплил проект, получил обновление метаданных. В рамках проекта могут и более сложные макры работать которые могут отслеживать изменения в СУБД хоть по таймеру, хоть как. Ну, и при изменении тупо махать список типов.

И какими же механизмами будут пользоваться эти самые "более сложные макры"?
В какой момент они будут цепляться к СУБД?
Как на это будт реагировать интелисенс внутри проекта?

Я уж не говорю про то что вместо одной строчки появился целый проект на пустом месте.

Ты бы хоть для разнообразия попытался понять о чем я говорю, а не начинал с ходу спорить со своим воображением.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.