Re[9]: бинд типов в макросах
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.04.10 15:12
Оценка: 6 (1)
Здравствуйте, Ziaw, Вы писали:

VD>>>Сори, конечно же TypeBuilder.Ast.t_extends.


VD>>Надо переименовать это дело во что-то приличное. У этих поляков с именами полный дурдом был.


Z>Может он internal? В Ast тоже не видно.


Просто тип свойства Ast — это TopDeclaration, а t_extends есть только у TopDeclaration.Class, TopDeclaration.Interface, TopDeclaration.Variant и TopDeclaration.Enum. Так что код должен быть примерно таким:
match (typeBuilder.Ast)
{
  | Class     as t => t.t_extends = xxx
  | Interface as t => t.t_extends = xxx
  | Variant   as t => t.t_extends = xxx
  | _              => () // для остальных типов ничего не делаем
}
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: DSL на макрах, не потерять автокомплит
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.04.10 16:11
Оценка: 2 (1)
Здравствуйте, Ziaw, Вы писали:

Z>Расскажи, плиз, если это можно рассказать кратко. Как дизайнить чтобы не потерять автокомплит?


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

Ну, а для этого нужно проектировать макры подобающим образом.

Предположим, что мы хотим получить описание добавления колонки следующего вида:
    addcolumn (Id to someTable)
    {
      PrimaryKey = true;
      Type = ColumnType.Integer();
    }


Для того чтобы можно было получить помлит-ворд для PrimaryKey и Type они должны как-то присутствовать в сгенерированном коде. Например, их можно объявить как локальные переменные.

Вот как может выглядеть реализация такого макроса (она ничего не делает, только выводит полученную информацию на консоль):
public variant ColumnType
{
  | Integer
  | String { len : int }
  | Float
}

namespace MigrationSytaxMacro
{
  public macro AddColumnMacro(name, tableName, body)
  syntax ("addcolumn", "(", name, "to", tableName, ")", body)
  {
    def name      = name.ToString();
    def tableName = tableName.ToString();

    <[ 
        // usesite - позволяет преодалеть гигееничность макросов и использовать цвета имен из контекста применения
        mutable $("PrimaryKey" : usesite) = false; 
        mutable $("Type" : usesite)       = ColumnType.String(-1); // начальные значения определяют тип переменных!
        
        $body; // тело

        // чтобы квази-цитаты не пересикались с $ в $-строках, вводим переменные...
        // их имена гигиеничны (не могут пересечься с аналогичными из пользовательского кода).
        def name        = $(name : string);
        def tableName   = $(tableName : string);
        def primaryKey  = $("PrimaryKey" : usesite);
        def ty          = $("Type" : usesite);
        
        System.Console.WriteLine($"PrimaryKey=$primaryKey Type=$ty name=$(name : string) tableName=$tableName");
     ]>
  }
}
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: бинд типов в макросах
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.04.10 16:23
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>А нужен ли этот общий интерфейс? Я не представляю общего интерфейса для гибернейта и тулкита.


Это тебе решать. Если нужны только разные реализации, то можешь только докидывать разную реализацию методов (приватных) в зависимости от провайдера.

Z>Зачем кого-то загонять в общий инетрфейс? Зачем пользователя гибернейта Я даю максимальную свободу и просто возможность не писать то, что и так указано — указано что класс DatabaseManager — подключаем тулкит, он DbManager, подбключаем гибернейт — он SessionFacade. Мне не надо в шаблоне приложения прописывать явное наследование от того или другого.


Это все к делу не относится. Главное, что наследование тут лишнее. Если тебе нужно можешь использовать макру Aggregation или еще что-то.

Z>С другой строны, если пользовтель захотел наследовать его от своего (непонятно зачем, но захотел),


А это уже его проблема. Если ему понадобится наследование реализации, то оно у него будет.

Z> так его право, пусть наследует от любого класса с реализацией GetTable[T]().


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

Z>Все что я хочу — не впихивать в шаблон приложения выделенное:


Z>
Z>[DatabaseManager]
Z>class Db : DbManager {}; 
Z>


Z>DRY, мы уже указали роль класса, если захотим явно указать предка — нет проблем, я не завязываюсь на реализацию.


Замечательно. Вот и убери необходимость наследования вовсе. Все что нужно просто докидывай к этому классу с помощью макросов.

Z>Скорее всего кроме того, что он IDisposable лично нрельсам от него ничего не нужно будет.


Это уже выходит за рамки твоей компетенции. Ту же реализацию IDisposable более удобно подключать через наследование реализации.

Короче, дизайн должен быть рассчитан на простоту использования и расширения. Чем меньше ты создашь ограничений и препонов для конечного пользователя-программиста, тем удобнее ему будет и тем выше он оценит твою реализацию.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: DSL на макрах, не потерять автокомплит
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.04.10 16:54
Оценка:
Здравствуйте, VladD2, Вы писали:

По поводу ColumnType...

Лично мне больше бы понравилось если этого описания не было бы вообще. Есть дотнетные типы. Их более чем достаточно для описания чего угодно. Нужно сделать грамотное отображения некоторого сабсэта дотнетных типов на типы СУБД.

Поддерживает поле null или нет тоже можно указывать вописании типов (в нотации нулабл-типов). Например:
ColName : int?.

В общем, чем короче и проще описание тем лучше.

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

В приведенном мною примере ColumnType описан в макрос-сборке — это очень плохой подход пригодный только для примеров и на скорую руку слепленных прототипов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: DSL на макрах, не потерять автокомплит
От: Ziaw Россия  
Дата: 14.04.10 17:45
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>По поводу ColumnType...


VD>Лично мне больше бы понравилось если этого описания не было бы вообще. Есть дотнетные типы. Их более чем достаточно для описания чего угодно. Нужно сделать грамотное отображения некоторого сабсэта дотнетных типов на типы СУБД.


Так и планируется, ColumnType внутренняя деталь реализации. Указывать его конечному пользователю не придется. Но обязательно будет такая возможность, т.к. дотнетовских типов к сожалению недостаточно для точного указания. Тот же string может мапиться на (n)char, (n)nvarchar, (n)text.

VD>Поддерживает поле null или нет тоже можно указывать вописании типов (в нотации нулабл-типов). Например:

VD>ColName : int?.

Тоже думал, со string такой номер не прокатит.

VD>Если же хочется использовать перечисление или вариант на подобии ColumnType, то его описание имеет смысл вынести в отдельную библиотеку, так чтобы не было нужны определять его в пользовательском проекте или генерировать макросами.

VD>В приведенном мною примере ColumnType описан в макрос-сборке — это очень плохой подход пригодный только для примеров и на скорую руку слепленных прототипов.

Я понял.
... << RSDN@Home 1.2.0 alpha 4 rev. 1468>>
Re[4]: DSL на макрах, не потерять автокомплит
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.04.10 17:58
Оценка: 1 (1)
Здравствуйте, Ziaw, Вы писали:

Z>Так и планируется, ColumnType внутренняя деталь реализации. Указывать его конечному пользователю не придется. Но обязательно будет такая возможность, т.к. дотнетовских типов к сожалению недостаточно для точного указания. Тот же string может мапиться на (n)char, (n)nvarchar, (n)text.


Дык и указывай эти детали в виде дополнительного синтаксиса или атрибутов.

В прочем, если это внутренняя реализация и пользователь не будет вынужден указывать эти самые ColumnType, то ОК. Вопрос снят. Просто в твоем коде он присутствовал явно в пользовательском коде.

VD>>Поддерживает поле null или нет тоже можно указывать вописании типов (в нотации нулабл-типов). Например:

VD>>ColName : int?.

Z>Тоже думал, со string такой номер не прокатит.


Это в C# не прокатит. А в немерле, пока код является PExpr-ешеном — прокатит. Главное, чтобы ты успел его разобрать до превращения в тот код который будет реально компилироваться.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.