По поводу разработки движка сайта
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.07 00:16
Оценка:
Решение уже принято. Пока мы решаем организационные вопросы и прочую дребедень можно уже потихонечку готовиться к работе.

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

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

Как следствие мы дложны во всю задействовать такие мощные средства как DSL-и, генерация кода и компонентный подход.

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

Это описание видится мне как некий DSL учитывающий как аспекты связанные с БД, так и аспекты связанные с бизнес-логикой и т.п.

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

Примечание
В качестве СУБД у нас будет использоваться MS SQL Server, но разработка будет вестись так, чтобы можно было в последствии сделать решение и на базе других СУБД.


По сему нам нужно написать библиотеку которая будет считывать метаописание (модель), сравнивать его с БД и генерировать SQL (T-SQL в случае MS SQL) приводящий структуру БД в соответствие с моделью.

Более подробно этот процесс можно расписать так:
1. Этот код считывает описание модели из DSL.
2. Преобразует модель в некий объектный вид (набор ООП-объектов или варианты, сейчас не важно).
3. Считывает описание структуры БД.
4. Преобразует описание структуры БД в объектный вид аналогичный п. 2.
5. Сравнивает два описания (полученные на шагах 2 и 4).
Для всех несоответствий вызывает методы генерации структуры БД.
6. Методы генерации генерируют SQL-DDL-скрипт модифицирующий структуру БД. Для того чтобы генерация DDL-скриптов не стала сущим адом. Скрипт для каждой части стркутры БД описывается в виде текстового шаблона (отдаленно напоминающего $-строку Nemerle).
7. Вызываются макры генерации Nemerle-кода необходимого для поддержки сущностей описанных в модели.

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

Это позволит нам хранить в репозитории SVN только описание модели (в текстовом), и синхронизировать структуру БД при запуске приложения на исполнение.

Это потребуется нам чтобы вести параллельную разработку включающую изменение структуры БД и избавит от проблем ручной синхронизации структуры БД и т.п.

Доступ к данным мы предполагаем вести с помощь Linq2SQL (бывших DLinq) или механизма его заменяющего.

Такой подход позволит решить следующие проблемы:
1. Избавиться от лишнего (оберточного) кода (функций, вся суть которых заключается в абстрагировании прикладного кода от работы с API БД).
2. Сделать работу с СУБД статически типизированной.
3. Прозрачно реализовать ряд важных сервисных функций типа — защиты, постраничной прокрутки (пэйджинга), кэширования данных и т.п.

За счет наличия модели возможно удастся избавиться от возни с джоинами и т.п., а так же статически (во время компиляции и в IDE) проверять соответствие запросов модели.

ЗЫ

Более подробно о движке таксовых шаблонов и поддержке Linq2SQL будет сказано в сообщениях ниже.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Движок текстовых шаблонов
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.07 00:29
Оценка:
В первую очередь нам нужен движек текстовых шаблонов.
По сути он будет похож на сегодняшнюю $-строку, но все же будет отличаться некоторыми расширенными возможностями:
1. Главное отличие заключается в том, что шаблон должен жить не сам по себе, а в составе и при непосредственном взаимодействии с другими шаблонами. Такие шаблоны объединяются в группу шаблонов.
2. Все шаблоны группы должны использовать для генерации текста единый для группы StringBuilder. Это обеспечит высокую скорость генерации текста.
3. Шаблоны должны позволять рекурсивное применение.
5. У шаблона должно быть описание входных параметров. Они могут исползовать в $ и ..$ конструкциях.

Группы шаблонов я вижу себе в виде класса (возможно помеченного неким атрибутом). Например:
[StringTemplateGroup]
class MyStringTemplateGroupe
{
    ...
}

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

[StringTemplateGroup]
class MethodGenerator
{
    // Описывает генерацию индекса.
    public virtual CreateIndex(index : Index, table : Table, isClustered : bool,
                                         isUnique : bool) : string StringTemplate 
    <[
    CREATE $(Unique(index.IsUnique)) $(Clustered(index.IsClustered)) INDEX $(Quot(index.Name)) ON $(Quot(table))
    (
      ..$(index.EntryColumns; "\n"; entry => $(entry.Column) $(Direction(entry.IsAscending)))
    )
    ]>
    
    // Генерирует выражение удаления индекса.
    // name - имя индекса подлежащего удалению.
    // table - имя таблицы индекс которой требуется удалить.
    public virtual DropIndex(name : string, table : string) : string StringTemplate <[
    DROP INDEX $Quot(name)$ ON $Quot(table)$
    ]>
    
    // Добавляет к имени символы цитирования. Это позволяет именам содержать
    // пробельные символы и пересекаться с ключевыми словами
    protected virtual Quot(name : string) StringTemplate <[
    [$name]
    ]>

    // Выводит сточку "UNIQUE" если isUnique равен true.
    // Это просто фукнция! Ее тело не является шаблоном.
    protected virtual Unique(isUnique : bool) : string
    {
      if (isUnique) " UNIQUE" else ""
    }

    ...
    
    // Выводит сточку ASC" если isAscending равен true или "DESC" в обратом случае.
    protected virtual Direction(isAscending : bool) : string
    {
      if (isAscending) "ASC" else "DESC"
    }
    
    ...
}

Общая идея такова. Данный код обрабатывается макросами и преобразуется в эффективный код генерации строк (с использованием StringBuilder-а).

Для каждого шаблона в группе создается две функции одна срытая имеющий прототим:
protected ИмяШаблона(список_параметров_шаблона) : void;

А другая имеющая прототип аналогичный описанному в группе. В случае рекурсивного вызова шаблонов вызывается скрытая функция. Это исключает лишние преобразования в строку, так как скрытая версия функции выводит генерируемый текст в StringBuilder.
Публичную функцию может вызвать пользователь. При этом внутренний StringBuilder сбрасывается, производится вызов скрытой версии фукнции, а затем содержимое внутреннего StringBuilder-а преобразуется в строку и возвращается наружу как возвращаемое значение функции.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
[Движок текстовых шаблонов]: Проблемы компилятора
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.07 00:39
Оценка:
Для реализация движка текстовых шаблонов видимо потребуется расширение компилтора.

Если я не прав, то предложите свой подход.

Опишу проблему...

В принципе ограниченную версию движка можно сделать и сейчас на базе лексических макросов.
Но это решение имеет несколько неприятных моментов:
1. Мы не имеем полного контроля над текстом, и, стало быть, придется восстанавливать текст из ткенов. При этом часть информации может теряться. Например, не все токены могут корректно преобразовываться обратно в текст. Да и мы теряем контроль над пробелами, а они очень важны для такого движка, ведь надо контролировать отступы. Можно конечно попытаться добраться до текста исходного файла, но это довольно сложно и криво.
2. В Nemerle токены скобок должны быть парными. Так что если текст должен будет содержать не парные скобки, то у нас будут проблемы.
3. Не все что можно описать текстом можно выразить токенами. В следствии этого мы можем поиметь проблем в некоторых случаях.

Оптимально, чтобы тело шаблона рассматривалось как просто плоский текст.

Так вот Nemerle не позволяет это сделать. У него просто нет таких низкоуровневых маросов.

По уму их надо бы приделать. Но тут встает вопрос – как?

Собственно мысли по этому поводу и интересуют.

При обдумывании этой проблемы прошу обязательно учесть два аспекта:
1. Очень важно чтобы решение не затормаживало парсинг. По этому вводить дополнительные проверки каждой лексемы не желательно.
2. Решение должно хорошо вписываться в язык.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Поддержка Linq2Sql
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.07 00:43
Оценка:
Одной из проблем которую нам надо решить – это встраивание в Nemerle функциональности Linq2Sql или аналогичной ей.

Просто Linq можно встроить в Nemerle исключительно средствами макросов. Даже интелисенс заработает на ура. Ввел несколько макросов и все.

Но Linq2Sql – это куда более серьезное решение. Похоже, что без изменения в компиляторе (направленного на распознавания типа Expression<T> и преобразования в него AST) нам не обойтись.

Отсюда перед нами стят задачи:
1. Нлубже разобраться в механизмах Linq2Sql.
2. Понять можно ли обойтись при его реализации без изменения в компиляторе.
3. Интегрировать Linq2Sql.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Поддержка Linq2Sql
От: noetic Украина Систематизация автоматизации
Дата: 11.04.07 01:41
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Просто Linq можно встроить в Nemerle исключительно средствами макросов. Даже интелисенс заработает на ура. Ввел несколько макросов и все.


VD>Но Linq2Sql – это куда более серьезное решение. Похоже, что без изменения в компиляторе (направленного на распознавания типа Expression<T> и преобразования в него AST) нам не обойтись.


Хмм... А разве все это не спрятано в самом Linq2Sql?
Что мешает просто написать макрос, который превращает выражение типа (упрощенно)
def t = Table.[Employee]();
def res = from e in t where e.Name = "Vasya" select e;
в
def t = Table.[Employee]();
def res = t.Where( e: Employee  => e.Name == "Vasya").Select( e: Employee => e);

вернее, чем это отличается от преобразования вида
def lst = aray[1, 2, 3];
def res = from x in lst where x > 0 select x;
в
def lst = aray[1, 2, 3];
def res = lst.Where(x : int => x > 0).Select(x : int => x);

Re[2]: Поддержка Linq2Sql
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.07 01:56
Оценка:
Здравствуйте, noetic, Вы писали:

N>Хмм... А разве все это не спрятано в самом Linq2Sql?


Что, то? Linq2Sql оперирует Expression<> в который компилятор C# 3.0 запаковывает AST лямбд переданных в качетве параметра тип которого Expression<>.

N>Что мешает просто написать макрос, который превращает выражение типа (упрощенно)


N>
N>def t = Table.[Employee]();
N>def res = from e in t where e.Name = "Vasya" select e;
N>

N>в
N>
N>def t = Table.[Employee]();
N>def res = t.Where( e: Employee  => e.Name == "Vasya").Select( e: Employee => e);
N>


Ничего не мешет. Но это функциональность Linq, а речь идет о Linq2Sql. Там вместо лямбд фукнциям нужно передавать AST этих лямбд.

То есть приведенный тобой пример должен быть переписан более сложным обрзом:
def res = t.Where(ToLinqExpression(<[ e => e.Name == "Vasya" ]>)).Select(ToLinqExpression(<[ e => e ]>));

Причем в общем-то макрос наверно такой сделть можно, но вот хотелось, чтобы можно быо писать точно так же как в C# 3.0:
def res = t.Where(e => e.Name == "Vasya").Select(e => e);

А вот это уже без изменений в компиляторе вряд ли получится.

Хотя опять же допускаю, что я просто где-то заблуждаюсь.

ЗЫ

Кстати, select тут совершенно лишний.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Поддержка Linq2Sql
От: ie Россия http://ziez.blogspot.com/
Дата: 11.04.07 03:31
Оценка: 34 (1)
Здравствуйте, VladD2, Вы писали:

VD>Ничего не мешет. Но это функциональность Linq, а речь идет о Linq2Sql. Там вместо лямбд фукнциям нужно передавать AST этих лямбд.


VD>То есть приведенный тобой пример должен быть переписан более сложным обрзом:

VD>
VD>def res = t.Where(ToLinqExpression(<[ e => e.Name == "Vasya" ]>)).Select(ToLinqExpression(<[ e => e ]>));
VD>


Тут "<[" и "]>" пожалуй лишние.

VD>Причем в общем-то макрос наверно такой сделть можно, но вот хотелось, чтобы можно быо писать точно так же как в C# 3.0:

VD>
VD>def res = t.Where(e => e.Name == "Vasya").Select(e => e);
VD>

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

Если таки реализовать Extension Macros, то повторить C#-овский синтаксис можно и на макросах.
А можно пойти другим путем, например, ввести альтернативный ситнаксис для Expression Trees, например: <@ e => e.Name == "Vasya" @>.
Но и тот и другой путь требует изменений в компиляторе.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Превратим окружающую нас среду в воскресенье.
Re[4]: Поддержка Linq2Sql
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.07 17:18
Оценка:
Здравствуйте, ie, Вы писали:

VD>>То есть приведенный тобой пример должен быть переписан более сложным обрзом:

VD>>
VD>>def res = t.Where(ToLinqExpression(<[ e => e.Name == "Vasya" ]>)).Select(ToLinqExpression(<[ e => e ]>));
VD>>


ie>Тут "<[" и "]>" пожалуй лишние.


Да, согласен. ToLinqExpression можно сделать макросом. Но все равно видеть эти костыли не очень хочется. Лучше малость поптчить компилятор.

ie>Если таки реализовать Extension Macros, то повторить C#-овский синтаксис можно и на макросах.


Да, это так, но Linq2Sql уже содержит список функциий-расширений которые совершенно конкретный тип.
Если бы Linq2Sql делался целиком на Nemerle, то твое предложение было бы пожалуй самым подходящим.

ie>А можно пойти другим путем, например, ввести альтернативный ситнаксис для Expression Trees, например: <@ e => e.Name == "Vasya" @>.

ie>Но и тот и другой путь требует изменений в компиляторе.

А какой в этом смысал? По-моему, это совершенно бессмысленно.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Поддержка Linq2Sql
От: WolfHound  
Дата: 11.04.07 19:47
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>То есть приведенный тобой пример должен быть переписан более сложным обрзом:

VD>
VD>def res = t.Where(ToLinqExpression(<[ e => e.Name == "Vasya" ]>)).Select(ToLinqExpression(<[ e => e ]>));
VD>

ИМХО ничто не мешает сделать като так
def res = linq t.Where(e => e.Name == "Vasya").Select(e => e );

по аналогии с lazy и late
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Поддержка Linq2Sql
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.07 21:22
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

WH>ИМХО ничто не мешает сделать като так

WH>
WH>def res = linq t.Where(e => e.Name == "Vasya").Select(e => e );
WH>

WH>по аналогии с lazy и late

Криво, по-моему.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: [Движок текстовых шаблонов]: Проблемы компилятора
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.07 21:22
Оценка:
Ну, так есть идеи по данному вопросу?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: [Движок текстовых шаблонов]: Проблемы компилятора
От: Сергей Туленцев Россия http://software.tulentsev.com
Дата: 11.04.07 22:40
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ну, так есть идеи по данному вопросу?


Больно ты мудрёного хочешь, боярин. Дай три дня сроку.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Re[3]: [Движок текстовых шаблонов]: Проблемы компилятора
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.07 22:53
Оценка:
Здравствуйте, Сергей Туленцев, Вы писали:

СТ>Больно ты мудрёного хочешь, боярин. Дай три дня сроку.




Ну, могу попробовать по подробнее описать... Или просто время на обмысливание надо?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Поддержка Linq2Sql
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.07 23:46
Оценка:
Здравствуйте, ie, Вы писали:

Кстит, не желаешь по участвовать в разработке нового движка?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: [Движок текстовых шаблонов]: Проблемы компилятора
От: Mirrorer  
Дата: 12.04.07 05:42
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>Ну, могу попробовать по подробнее описать... Или просто время на обмысливание надо?

Лучше поподробнее плз.
Я посмортел на проект, который реализовывает String Templates на шарпе, ты ссылку давал.
И не смог понять каким именно образом ты хочешь расширить его возможности и почему появляются проблемы при реализации на Немерле.
"Если Вы отличаетесь от меня, то это ничуть мне не вредит — Вы делаете меня богаче". Экзюпери
Re[5]: Поддержка Linq2Sql
От: WolfHound  
Дата: 12.04.07 09:27
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Криво, по-моему.

Ну можно вобще сделать макрос уровня сборки. И будет практически как в C#.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: [Движок текстовых шаблонов]: Проблемы компилятора
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.07 14:50
Оценка: 14 (1)
Здравствуйте, Mirrorer, Вы писали:

M>Я посмортел на проект, который реализовывает String Templates на шарпе, ты ссылку давал.

M>И не смог понять каким именно образом ты хочешь расширить его возможности и почему появляются проблемы при реализации на Немерле.

Расширять его возможности я не хочу. Скорее сужать. Ведь у нас есть полноценный ФЯ, а значит многие возможности String Template можно повторить за счет этого и не стоит встраивать их в язык.

Я хочу сделать "вмонтированную" в Немерле версию String Template. Причем хочу чтобы от исходного варианта (т.е. String Template) наша реализация отличалась следующим:
1. Обрабатывалась на стадии компиляции и превращалась в эффективный код (String Template интерпретируется).
2. В части описания правил и групп шаблонов использовала синтаксис классов и методов Немерле.
3. В качестве вставок использовать не String Template-тные соглашения, а соглашения используемые в $-строках Немерле.

Вот в этом собщении
Автор: VladD2
Дата: 11.04.07
. Я описал как должны выглядеть шаблоны. Ладно, приведу еще раз в сокращенном виде:
[StringTemplateGroup]
class MethodGenerator
{
    // Описывает генерацию индекса.
    public virtual CreateIndex(index : Index, table : Table, isClustered : bool,
                                         isUnique : bool) : string StringTemplate 
    <[
    CREATE $(Unique(index.IsUnique)) $(Clustered(index.IsClustered)) INDEX $(Quot(index.Name)) ON $(Quot(table))
    (
      ..$(index.EntryColumns; "\n"; entry => $(entry.Column) $(Direction(entry.IsAscending)))
    )
    ]>
    
    // Добавляет к имени символы цитирования. Это позволяет именам содержать
    // пробельные символы и пересекаться с ключевыми словами
    protected virtual Quot(name : string) StringTemplate <[
    [$name]
    ]>

    // Выводит сточку "UNIQUE" если isUnique равен true.
    // Это просто фукнция! Ее тело не является шаблоном.
    protected virtual Unique(isUnique : bool) : string
    {
      if (isUnique) " UNIQUE" else ""
    }

    ...
}


Обрати внимание, что сами "шаблоны" имеют описание почти аналогичное описанию методов Немерле. Но есть и различия. Они заключаются в теле шаблона и его интерпретации.

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

Есть следующие типы макросов:
1. Метаатрибуты.
2. Лесемные макросы.
3. Макросы-выражения.

Первый и последний пукнтк вообще (похоже) не то что нужно.
Лексемные макросы тоже подходят не совсем. Рассмотрим один шаблон:
    // Описывает генерацию индекса.
    public virtual CreateIndex(index : Index, table : Table, isClustered : bool,
                                         isUnique : bool) : string StringTemplate 
    <[
....CREATE $(Unique(index.IsUnique)) $(Clustered(index.IsClustered)) INDEX $(Quot(index.Name)) ON $(Quot(table))
....(
....  ..$(index.EntryColumns; "\n"; entry => $(entry.Column) $(Direction(entry.IsAscending)))
....)
....]>

Я намерянно заменил незначащие пробелы точками. По идеологии String Template они должны игнорироваться. Более того, при раскрытии шаблонов значащие отступы должны накапливаться. Тогда мы можем, например, описать шаблон класса, все члены которого имеют отсупы, шаблон метода, все выражения которого имеют отсуп, и шаблон выражения, кождое вложенное подвыражение которого тоже имеет отсуп (прчем рекурсивно). Так вот при раскрытии шаблонов отступы должны складываться и в итоге должен получаться правильно отформатированный код.

Это была первая проблема. Суть ее в том, что в лексемах теряется информациях о "ведущих" пробелах (т.е. о символах идущих в начале строки. Как в рпочем и о других пробелах (под словом "пробем" так же могут проходить и табуляции).

Вторая проблема заключается в том, что токены Немерла могут не совпадать с токенами генерируемого языка. Ведь по усти для String Template тело шаблона — это произвольный тест с активными вставками начинающимися с $ или ..$. Но то что можно выразить текстом не всегда можно вырзить лексемами (токенами) Немерле. Плюс у Немерле есть одно ограничение. Скобки в этом языке обязаны быть парными! Шаблоны же могут содержать непарные скобки.




Это было описание проблемы. Теперь мои мысли.

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

В нашем случае такой макрос встречая конструкцию:
StringTemplate  <[ ... ]>

выделял бы содержимео <[ ... ]> в виде строки и возвращал бы набор токенов:
{ StringTemplateParser(...) }

где StringTemplateParser — это макрос который на одной из следующих стадий будет разбирать тело шаблона. А ... — это преобразованное в текстовую строку содержимое шаблона.

Так вот. Основная проблема с подобным расширением компилятора — это скорость. Ведь чтобы передать управление внешнему лексеру нужно что-то распознать в потоке лексем. Самым логичным, на мой взгляд, будет распознование ключевого слова. Но на сегодня обработка ключевых слов на стадии лексического разбора ограничивается их расознованием (путем поиска идентификатора в структуре данных Set) и оборачиванием токеном Keyword. Если добавить туда еще каую-то логику то может получиться замедление. А это крайне не желательно.

Собственно вопрос и заключается как же оптимальным образом реализовать задуманное?
Нужно ли расширять компилятор вводя новый тип макросов (авторы языка весьма не радостно приняли эту идею)?
И нет ли каких-то альтернативных путей на которые я не обратил внимания.
Короче любые мысли будет интересны.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Поддержка Linq2Sql
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.07 15:25
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Ну можно вобще сделать макрос уровня сборки. И будет практически как в C#.


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

Подключайся к проекту. Создадим группу работы над интеграцией Линка, обмозгуем и реализуем все как надо.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Поддержка Linq2Sql
От: ie Россия http://ziez.blogspot.com/
Дата: 12.04.07 16:57
Оценка:
Здравствуйте, VladD2, Вы писали:
ie>>А можно пойти другим путем, например, ввести альтернативный ситнаксис для Expression Trees, например: <@ e => e.Name == "Vasya" @>.
VD>А какой в этом смысал? По-моему, это совершенно бессмысленно.

Если честно, я не совсем представляю, как такие (t.Where(e => e.Name == "Vasya").Select(e => e)) случаи обрабатывает C#-овский компилятор:
public static IQueryable<T>  Where<T>(this IQueryable<T>  source, Expression<Func<T, bool>> predicate) {...}
public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool>             predicate) {...}

...

queryable .Where(x => x.Name == "Vasya"); // тут лямбда превращается в Expression
Expression<Func<int,int>> e = x => x + 1; // и тут лямбда превращается в Expression

enumerable.Where(x => x.Name == "Vasya"); // тут лямбда остается лямбдой
Func<int,int> f = x => x + 1; // тут лямбда остается лямбдой

Единственное, что приходит на ум — это валидация типа параметра и при необходимости трансформация лямбды в Expression. С одной стороны этот подход позволяет не парится и писать с точки зрения пользователя везде однотипный код. А с другой стороны — это хардкодинг в компиляторе. Ясно дело, что чем таких хардкодингов меньше, тем лучше.
Вот так вот, например, уже написать нельзя:
var z = x => x + 1;

В Немерле эта болезнь скорее всего не будет присутствовать как класс, но все же я не до конца уверен, что удастся гладко вписать Expression-ы.
Don Syme в F# пошел другим путем. Он решил, что хардкодинг связаный с типами в компиляторе лишний, а стоит остановиться на хинте компилятору. Собственно, в F# <@ ... @> означают Expression.
У меня на этот счет двоякое мнение. С одной стороны <@ @> лишние, а с другой, начав хардкодить часные случаи, можно нехило огрести в последствии.

VD>Кстит, не желаешь по участвовать в разработке нового движка?


Благое дело, завтра с утра займусь выполнением пунктов
Автор: VladD2
Дата: 12.04.07
.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Превратим окружающую нас среду в воскресенье.
Re[6]: Поддержка Linq2Sql
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.07 21:05
Оценка:
Здравствуйте, ie, Вы писали:

ie>Единственное, что приходит на ум — это валидация типа параметра и при необходимости трансформация лямбды в Expression. С одной стороны этот подход позволяет не парится и писать с точки зрения пользователя везде однотипный код. А с другой стороны — это хардкодинг в компиляторе.


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

ie> Ясно дело, что чем таких хардкодингов меньше, тем лучше.


Ну, надо признать, что их не так много. Вот еще разные поддержки IEnumerable<> и т.п. захардкожены.

ie>Вот так вот, например, уже написать нельзя:

ie>
ie>var z = x => x + 1;
ie>


Ну, такой пример написать нельзя не только из-за этого хардкода. В C# еще нет фнкционального типа, а к делегату приводить неполучится, так как сразу несколько делегатов могут совпадать по сигнатуре.

ie>В Немерле эта болезнь скорее всего не будет присутствовать как класс, но все же я не до конца уверен, что удастся гладко вписать Expression-ы.


Мне тоже кажется, что все же проще будет захардкодить поддержку Expression<> в компиляторе. Но естественно все лучше обдумать, чтобы потом не жалеть.

ie>Don Syme в F# пошел другим путем. Он решил, что хардкодинг связаный с типами в компиляторе лишний, а стоит остановиться на хинте компилятору. Собственно, в F# <@ ... @> означают Expression.

ie>У меня на этот счет двоякое мнение. С одной стороны <@ @> лишние, а с другой, начав хардкодить часные случаи, можно нехило огрести в последствии.

Решение F# уродливое. Ну, да без полноценных макросов квази-цитирование тоже еще та глупость. В общем, странные они. Дерут вроде у других, но как-то не полностью... частично.

ie>Благое дело, завтра с утра займусь выполнением пунктов
Автор: VladD2
Дата: 12.04.07
.


Давай.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.