Re: Размышления о типизаторе для Н2
От: catbert  
Дата: 31.05.11 19:15
Оценка: 12 (1) +3
Здравствуйте, WolfHound, Вы писали:

WH>Примеры пойдут ответами на это сообщение.


Предлагаю или конкретно описать задачу, ее решение и конкретно что делается в коде, и какие проблемы у if из N1, или спорить с Владом в скайпе.

Потому что я не уверен, что хотя бы читателей форума вообще понимает о чем речь.
Re[17]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 27.06.11 22:18
Оценка: 1 (1) +2
Здравствуйте, VladD2, Вы писали:

VD>Вот это грубейшая ошибка. Н без иф-а не перестает быть Н.

Это у тебя каша в голове.
Это другой язык просто по определению.
Ибо он состоит из другого множества строк.

VD>А тебе не кажется, что есть огромная разница между переписыванием одного языка в свой же саб-сэт (а то и супер-сет, так как переписанный код так же может быть засахаренным), и переписывании одного языка в другой?

Нет.

VD>Переписывание X в X делается тупым квази-цитированием. Переписывание, X в Y требует наличия кучи дополнительной информации (тех же типов и т.п.).

Ну-ну. Про foreach и компанию уже забыл?

VD>Тут вообще очень большой вопрос. Твоя схема дико избыточна. Если мы произвели типизацию, то типизация сгенерированного по нему нетипизированного кода становится явно избыточным действием. Причем, так как сущности могут раскрываться друг в друга многократно будет не просто повторная типизация, а многократная повторная типизация. Тут и до экспоненты не далеко.

Повторной типизации не будет. Экспоненты тоже.

VD>Я предлагаю отделить мух от котлет.



VD>Сначала раскрываем все макросы и производим типизацию. В итоге получаем код без макросов (только с АСТ для которого вычислены типы. Потом то что получилось преобразуем в другой язык. Это делаем спомощью максимально формализованного (формально описанного на неком ДСЛ-е) маппера.

А тебе не кажется что вот этот вот маппер это то же самое, что переписыватель кода в случае с макрами?

VD>Базовый язык — это язык в котором нечего раскрывать.

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

VD>Совершенно по хрену когда происходит раскрытие макроса, до и или после типизации. Главное в макросе то, что он раскрывается в тот же язык (а значит может использовать все его примитивы). Преобразование же другой язык — это другое действие. При этом будет происходить изменение объектной модели.


Вот есть у нас макра LINQ это уже новый язык или еще нет?
А ComputationExpressions?
А XmlLiterlas?
А PegGrammar?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[13]: Размышления о типизаторе для Н2
От: Silver_S Ниоткуда  
Дата: 23.06.11 18:27
Оценка: 2 (1) +1
WH>Ибо семантика языка задает смысл каждой строки языка.
WH>А это все проверки на то принадлежит ли строка языку. Те синтаксис.
WH>Но Влад верит, что КС грамматика задает сам язык. То, что она задает не язык, а надмножество языка он не понимает.
Какая разница как все называть, если реализация от этого не изменится.
Да и если все ошибки которые выдает компилятор на синтаксические конструкции, называть синтаксическими, и ответом на вопрос принадлежит ли строка языку.
Тогда получится что язык C# и его компилятор недетерминированны (или почти) — т.е. ошибка может выскочить а может и не выскочить, как повезет.
Сомневаюсь что кто-то может ответить на вопрос(не исполняя части кода) — "Выскочит ли ошибка компиляции на таком коде" ?
const int Original = 4;
const double             
    N2 = 0.1,
    N3 = 3.5;
const int N = (int)(( (Original+N2)*N3 - N2*N3) / N3);        
                
int Func()
{
    if (N == Original)
       return 0;
}


А если с таким значением? : const int Original = 2;
Здесь можно это выражение редуцировать в аналитическом виде , а почему бы и нет? Получается N==Original
Если вычислять численно, то результат зависит от погрешностей в арифметическом процессоре (от деталей его реализации)

Так это комиилятор C# синтаксическую ошибку, либо выдает либо не выдает(как повезет), или уже семантическую?
Re[2]: Размышления о типизаторе для Н2
От: hardcase Пират http://nemerle.org
Дата: 31.05.11 15:03
Оценка: :))
Здравствуйте, catbert, Вы писали:

C>А я думал, Н2 будет просто отрефакторенный Н1.


Нет. Отрефакторенный N1 будет называеться N1.5 (т.е. без полторашки не разобраться).
/* иЗвиНите зА неРовнЫй поЧерК */
Re[16]: Размышления о типизаторе для Н2
От: hardcase Пират http://nemerle.org
Дата: 27.06.11 15:52
Оценка: +2
Здравствуйте, artelk, Вы писали:

WH>>Например в ПЕГе нет никаких терминалов. Так что вся твоя терминология строится на деталях реализации.

A>Вроде как есть.

Если мы строим PEG для разбора Unicode текста, то терминальны у нас — Unicode символы.
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 16:18
Оценка: 51 (1)
Здравствуйте, WolfHound, Вы писали:

В общем случае одному типу АСТ могут соответствовать несколько разных типов ТАСТ.
Наиболее яркий пример это ComputationExpressions. Там кроме стандартного использования через билдер могут быть и более тесно интегрированные решения. В частности array, list, enumerable, async,... Но об этом в другой раз.

Начем с простенького:
abstract ast Expression;

ast If : Expression
{
    syntax "if" "(" condition ")" trueExpression "else" falseExpression;
    condition       : Expression;
    trueExpression  : Expression;
    falseExpression : Expression;
}


Теперь заведем вспомогательные предикаты.
Эти и еще куча других предикатов будут в стандартной поставке.
pred ConvertibleTo(from : Type, itemType : Type)
mode (in, in) is semidet //Проверяет что один тип приводим к другому.
mode (in, out) is multi  //При помощи бектрекинга перебирает все типы к которым можно привести данный.
//multi по пому что тип как минимум можно привести к самому себе.
//Так что хоть один результат да будет.
//Реализацию выдумавать лень.

//Пытается найти тип к которому можно привести все типы из списка.
pred Unify(types : list[Type], result : Type)
mode (in, out) is semidet


abstract tast TypedExpression
for Expression//Сообщаем системе какой узел ast типизировать данным tast
{
    ExpressionType : out Type;
}

tast TypedIf : TypedExpression
for If
{
    trueType      = trueExpression.ExpressionType;//Локальные переменные.
    falseType     = falseExpression.ExpressionType;//Для краткости.
    conditionType = condition.ExpressionType;
    
    ConvertibleTo(conditionType, type(bool))
        @@@ $"Type of condition must be convertible to bool. But $(conditionType) not convertible to bool." condition.Location;

    Unify([trueType, falseType], ExpressionType)
        @@@ $"Typef of branches must be competible. $trueType and $falseType incompatible" this.Location;
}
rewrite//Понижение уровня языка.
//В режиме ИДЕ никогда не выполняется.
{
    <[
        match ($condition)
        {
            | true  => $trueExpression;
            | false => $falseExpression;
        }
    ]>
}

После @@@ сообщение об ошибке которое показывается, если данное правило обламалось.

rewrite может генерировать недотипизированный АСТ.
В этом случае производится локальная дотипизация.
Если она выявила ошибки, то они считаются ошибками реализации и доводятся до пользователя с соответствующей пометкой.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 14:54
Оценка: 10 (1)
Сразу оговорюсь, что я считаю схему
Автор: VladD2
Дата: 21.05.11
предложенную Владом неадекватно переусложненной и крайне не гибкой.
Поэтому я не буду делить AST на AST, SST, TSST, TAST.
У меня будет AST это то что выдает парсер и TAST это то что получается при типизации AST.

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

Для того чтобы сделать типизатор нам нужно формализовать 3 вещи:
1)Описание структуры типа.
Даже в немерле понадобятся как минимум две группы типов с разной структурой.
Типы выражений.
Типы паттернов.
Про пользовательские языки типа ПЕГ я вообще молчу. Там типы совсем другими получаются.
Можно конечно попытаться их унифицировать, но код типизации сразу обрастет костылями, которые разбираются где какой тип. Короче динамическая типизация во всей красе.

Также нужно не забыть про "многослойные" системы типов.
Это нужно, например для:
http://scholar.google.com/scholar?q=type+refinements+programming

Вывод типов производится в два этапа.
Сначала выводятся основные типы.
Потом "рафинированные".

2)Описание поиска имен.
Весь поиск имен во всех языках, которые я помню сводиться к очень простой схеме:
а) Поиск имени в иерархии областей видимости.
Смотрим в текущей области. Если не нашли, поднимаемся этажом выше. И так пока не найдем или не достигнем последней области видимости.

Требование объявления перед использованием решается заведением новой области видимости при объявлении переменной.

б) Доступ к члену объекта/пространства имен/...

3)Собственно язык описания правил вывода типов.
Мои мысли в данный момент крутяться вокруг Mercury.
Несколько упрощенный Mercury будет отличной основой для создания языка описания типизации.
Я выбрал Mercury ибо типизация это поиск с откатами. Как раз то вокруг чего построен этот язык.
Пролог пошёл лесом, ибо Mercury это пролог сделанный правильно.

Примеры пойдут ответами на это сообщение.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 19:21
Оценка: :)
Здравствуйте, catbert, Вы писали:

C>Предлагаю или конкретно описать задачу, ее решение и конкретно что делается в коде, и какие проблемы у if из N1, или спорить с Владом в скайпе.

Когда Влад через пару лет мне заявит что это он придумал типизаровать АСТ я его в эту тему буду тыкать.

C>Потому что я не уверен, что хотя бы читателей форума вообще понимает о чем речь.

Не стоит говорить за всех.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 15:41
Оценка: -1
Здравствуйте, WolfHound, Вы писали:

VD>>Пример похоже настолько бредовый, что я него не понял. Что он добивается то?

WH>Чтобы string можно было в if засунуть.

Это типа такой странный способ приведения к булеву типу когда null интерпретируется как false?

Пример более чем станный. С этим люди боролись, боролись, а ты решил это как преимущество показать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 01.06.11 20:36
Оценка: -1
Здравствуйте, VladD2, Вы писали:

VD>Не, не так. Правильная цепочка в твоем случае блудет такая:

>>Нет трансформации АСТ -> Нет потери информации -> нет автодополнения (делаем его вручную для каждого языка и макроса)
В моем варианте у компилятора всегда есть вся информация.
Он знает все типы.
Он знает, где какие имена объявлены.
Пользователь не ломает своими шаловливыми ручками информацию.
Так что хватит разводить демагогию и выдавать желаемое за действительное.

VD>Ну, а про "Нет трансформации АСТ" ты мне расскажешь когда будешь описывать то как ты реализуешь макру linq.

Да нет с ней никаких проблем.
Типизирую точно также как ".".
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Размышления о типизаторе для Н2
От: hi_octane Беларусь  
Дата: 01.06.11 22:28
Оценка: +1
C>Предлагаю или конкретно описать задачу, ее решение и конкретно что делается в коде, и какие проблемы у if из N1, или спорить с Владом в скайпе.
C>Потому что я не уверен, что хотя бы читателей форума вообще понимает о чем речь.

Нее, не надо скайп. Они там доспорятся так, что в нужный момент те кто понимают — и встрять не успеют и не окажется в Н2 какой-нить очень нужной фичи

Задача простая: в Н1 макрос — в зависимости от задачи, может быть простой, довольно декларативный, с квазицитатами и прочими радостями. А как надо что-то большее чем обёртка над тем что уже есть, то может получиться ну очень сложный, императивный, творящий непонятные пакости над AST. А хочется декларативно, со всеми радостями, и чтоб IDE на лету подхватывал...

А VladD2 и WolfHound решают как же эту радость сделать "правильно". Пока весь спор сосредоточен вокруг того можно ли типизировать макросы без их раскрытия (предлагает WolfHound), или же есть такие макросы, которые только после типизирования и можно раскрыть (в этом уверен VladD2).
Re[4]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.06.11 15:19
Оценка: :)
Здравствуйте, WolfHound, Вы писали:

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


_>>А VladD2 и WolfHound решают как же эту радость сделать "правильно". Пока весь спор сосредоточен вокруг того можно ли типизировать макросы без их раскрытия (предлагает WolfHound), или же есть такие макросы, которые только после типизирования и можно раскрыть (в этом уверен VladD2).

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

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

WH>В качестве доказательства свой теории он размахивает линком.

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

Аналогично чему? То есть мы таки переписываем все это дело в вызовы методов и типизируем?

WH>Вся проблема моего подхода в том, что я пока не до конца формализовал язык описания правил типизации. Но это вопрос времени.


Проблема твоего подхода в том, что он основан на вере. И ты упорно не хочешь воспринимать реалии окружающего мира. Все что не вписываются в твой подход ты смело обходишь стороной.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Размышления о типизаторе для Н2
От: artelk  
Дата: 22.06.11 16:13
Оценка: +1
Здравствуйте, VladD2, Вы писали:

Я, конечно, не копенгаген в этих ваших высоких материях. Сужу только на основании прочитанного из вашей дружественной беседы.
На сколько я понял, твой подход заключается в том, что должен быть базовый язык, для которого реализован типизатор и кодогенераторы под разные платформы. Плюс будут макросы, разворачивающиеся в этот базовый язык (и\или меняющие куски AST). Если кому-то захочется написать свой DSL или вообще свой отдельный язык, ему нужно просто написать макрос(ы)-транслятор(ы), преобразующие этот язык в AST базового языка. После этого он автоматом получит возможность компилировать программы, причем под различные платформы и т.п. Так?

Подход WH, на сколько я понял — это сделать настоящий парсер подмножества КЗ языков, покрывающее, по крайней мере, строготипизированные языки программирования. Обычный подход — это для КЗ языка программирования выделить КС-ный надъязык, реализовать для него парсер с построением AST и следующим этапом уже вручную пройтись по полученному AST, достраивая "семантические" связи, расставляя типы и выявляя ошибки, которые не смог отловить парсер. Под "семантикой" тут подразумевается как раз та часть языка, которая не покрывается грамматикой используемого в данном конкретном случае КС-ного надъязыка.
Если же делать "настоящий" парсер, разбирающий КЗ язык программирования, то в этом втором этапе надобность отпадает. Но в таком подходе типы выражений становятся сущностями этапа парсинга и они должны задаваться прямо как часть грамматики, что и пытается сделать WH (если я в чем-то не прав — скажите, плиз). Затея выглядит очень амбициозно. В таком подходе базовый язык, в который все транслируется, необязателен. Если и делать такой базовый язык, то он будет описан теми же средствами, что используются при определении макросов (а вообще, ими и исчерпываться). Отдельный типизатор тоже не нужен, т.к. сам он будет описан на том-же mercury-подобном языке и будет децентрализован и "размазан" по определениям макросов. Добавляя новый макрос и задавая правила его типизации мы тем самым разширяем "общий" типизатор этими правилами. Весь язык будет состоять из макросов, включающих в свое определение и правила типизации. Предлагать использовать существующий типизатор N1 для проверки концепции, заключающейся в том, чтобы не использовать внешний базовый язык и его типизатор несколько нелогично...

Вот
Re[13]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 23.06.11 11:48
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>Не савсем. Рассказы про КС-парсеры — это скажем так — пиар.

Это скажем так факты, основанные на теории формальных языков из которых вся терминология и пошла.

VD>На самом деле вся разница между нашими подходами заключается только в том допускается ли преобразование нетипизированного АСТ или нет. В планах WH точно так же есть КС-парсер который выдает на выходе нетипизированное АСТ.

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

VD>WH предлагает сделать то что не сделано у других — кроме генерируемого (но расширяемого) парсера он предлагает сделать генерируемый и расширяемый типизатора. И вот тандем парсера и типизатора он и называет КЗ-парсером (точнее не называет, а подразумевает, так как в слух он это не произносил).

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

VD>Базовый язык все равно будет. Вопрос только как его делать. Вручную или на базе все того же средства.

Один базовый язык на все случаи жизни не возможен теоритически.

VD>Идея лепить все с нуля для каждого языка — это заранее провальная идея.

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

VD>Ну, вот если сюда добавить, а точнее оставить, возможность делать нетипизированные преобразования (и что важнее, частично типизированные).

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

VD>И если так же ввести понятие базового языка (возможно неодного), то получится очень близко к тому что хочу в итоге получить я.

О как?!
Уже не одного.
Так ты же через базовый язык все собрался типизировать.
Или как?
И как ты собрался в таком случае некий ДСЛ транслировать в разные бызовые языки?

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

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

VD>Это не маленький такой (и не самый простой) код. Только на его отдадку можно убить несколько месяцев. А на базе солвера из Н1 его можно создать очень быстро и просто. Он, конечно, будет далек от идеала по производительности, но для прототипа этого и не надо.

Это по тому, что он написан руками.
А я собрался его генерировать.
Тут точно как с парсером.
Писать его руками озвереешь. А PegGrammar все сделает на раз.

Кстати заметь: artelk все понял правильно. Так что тут дело в тебе.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[12]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 23.06.11 11:48
Оценка: :)
Здравствуйте, artelk, Вы писали:

A>Подход WH, на сколько я понял — это сделать настоящий парсер подмножества КЗ языков,

Синтаксический анализатор.

A>покрывающее, по крайней мере, строготипизированные языки программирования.

Что такое строготипизированные языки программирования я так и не понял.
Это слишком мутный термин.

A>Обычный подход — это для КЗ языка программирования выделить КС-ный надъязык, реализовать для него парсер с построением AST и следующим этапом уже вручную пройтись по полученному AST, достраивая "семантические" связи, расставляя типы и выявляя ошибки, которые не смог отловить парсер. Под "семантикой" тут подразумевается как раз та часть языка, которая не покрывается грамматикой используемого в данном конкретном случае КС-ного надъязыка.

Использовать слово "семантика" в данном случае не верно.
Ибо семантика языка задает смысл каждой строки языка.
А это все проверки на то принадлежит ли строка языку. Те синтаксис.
Но Влад верит, что КС грамматика задает сам язык. То, что она задает не язык, а надмножество языка он не понимает.

Остальное правильно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[15]: Размышления о типизаторе для Н2
От: artelk  
Дата: 27.06.11 21:40
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Это у WolfHound-а стиль такой. Он вместо того чтобы просто что-то сказать выдает фантак сарказма.

Эх.. никто не безгрешен
Re[18]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.06.11 23:21
Оценка: -1
Здравствуйте, WolfHound, Вы писали:

VD>>Вот это грубейшая ошибка. Н без иф-а не перестает быть Н.

WH>Это у тебя каша в голове.
WH>Это другой язык просто по определению.
WH>Ибо он состоит из другого множества строк.



VD>>Переписывание X в X делается тупым квази-цитированием. Переписывание, X в Y требует наличия кучи дополнительной информации (тех же типов и т.п.).

WH>Ну-ну. Про foreach и компанию уже забыл?

Нет не забыл. Главное, что при переписывания foreach не требуются новые понятия. Переписанных код — это код на все том же языке, а форыч не более чем сахар.

VD>>Тут вообще очень большой вопрос. Твоя схема дико избыточна. Если мы произвели типизацию, то типизация сгенерированного по нему нетипизированного кода становится явно избыточным действием. Причем, так как сущности могут раскрываться друг в друга многократно будет не просто повторная типизация, а многократная повторная типизация. Тут и до экспоненты не далеко.

WH>Повторной типизации не будет. Экспоненты тоже.



VD>>Сначала раскрываем все макросы и производим типизацию. В итоге получаем код без макросов (только с АСТ для которого вычислены типы. Потом то что получилось преобразуем в другой язык. Это делаем спомощью максимально формализованного (формально описанного на неком ДСЛ-е) маппера.

WH>А тебе не кажется что вот этот вот маппер это то же самое, что переписыватель кода в случае с макрами?

Это у тебя каша в голове.
Макра переписывает в тот же язык (на выходе нет конструкций, вроде goto, отсутствующих в исходном языке), а случае с маппером они неизбежно будут.

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

VD>>Базовый язык — это язык в котором нечего раскрывать.

WH>Его не существует.

Это у тебя каша в голове.

WH>Нельзя создать базовый язык на все случи жизни.


Это у тебя каша в голове.
Базовый язык — это просто макры без тел преобразования в тот же язык. Макры описывающие только АСТ. Для таких макр будет обязательна типизация (так как именно их придется в итоге мапить в концептуально другой язык).

WH>Например, детерминированная финализация и полноценные продолжения существовать в рамках одного языка не могут.


Это у тебя каша в голове.

WH>Они просто разрушают семантику друг друга.


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

WH>Про языки с другим вычислительным базисом и говорить нечего.


Ну, вот и не будем.

VD>>Совершенно по хрену когда происходит раскрытие макроса, до и или после типизации. Главное в макросе то, что он раскрывается в тот же язык (а значит может использовать все его примитивы). Преобразование же другой язык — это другое действие. При этом будет происходить изменение объектной модели.

WH>
WH>Вот есть у нас макра LINQ это уже новый язык или еще нет?


Нет. Это у тебя каша в голове. Это чистый сахар.

WH>А ComputationExpressions?


Нет.

WH>А XmlLiterlas?


Нет.

WH>А PegGrammar?


Нет.

И на всякий случай еще раз — да, если надо, то можно будет воспользоваться типизацией до раскрытия, а так же поиском имен и т.п. Так что для PegGrammar будут все условия.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[19]: Размышления о типизаторе для Н2
От: gbear Россия  
Дата: 28.06.11 02:41
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>>>Вот это грубейшая ошибка. Н без иф-а не перестает быть Н.

WH>>Это у тебя каша в голове.
WH>>Это другой язык просто по определению.
WH>>Ибо он состоит из другого множества строк.
VD>

Влад, а можно таки пояснить свои "смешки" для особо одаренных? А то я вот давненько это всё читаю. И то, что говорит WolfHound мне в целом ясно и понятно. А вот "сакральность" твоих утверждений от меня зачастую ускользает.

VD>>>Переписывание X в X делается тупым квази-цитированием. Переписывание, X в Y требует наличия кучи дополнительной информации (тех же типов и т.п.).

WH>>Ну-ну. Про foreach и компанию уже забыл?
VD>Нет не забыл. Главное, что при переписывания foreach не требуются новые понятия. Переписанных код — это код на все том же языке, а форыч не более чем сахар.

"Не требуются новые понятия" значит. Они _[не]новые_ относительно чего?

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


Я правильно понимаю, что ты утверждаешь, что маппер это не "функция из АСТ в АСТ"?

VD>>>Базовый язык — это язык в котором нечего раскрывать.

WH>>Его не существует.
VD>Это у тебя каша в голове.

WH>>Например, детерминированная финализация и полноценные продолжения существовать в рамках одного языка не могут.

VD>Это у тебя каша в голове.
WH>>Они просто разрушают семантику друг друга.
VD>Это проблемы дизайна языка и типизации. Если конструкции не могут встречаться в одном выражении, то код типизации должен это проверить и выдать сообщение об ошибке. Если, может, то должны проверяться условия сосуществования.

А можно и мне тоже так:


WH>>Вот есть у нас макра LINQ это уже новый язык или еще нет?


VD>

VD>Нет. Это у тебя каша в голове. Это чистый сахар.

Влад, на самом деле _любой_ синтаксический макрос — _формально_ — определяет новый язык. Пусть сколь угодно малый и простой. Пусть. Но, таки, _новый_ (т.е. _другой_) язык. Выражений этого языка — их просто не существует в исходном. Вот и всё. А то, что выражения этого языка (определенного синтаксическим макросом) отображаются в выражения исходного языка — того, для которого этот "макрос" создан — абсолютно ничего не меняет.
Re: Размышления о типизаторе для Н2
От: catbert  
Дата: 31.05.11 15:00
Оценка:
А я думал, Н2 будет просто отрефакторенный Н1.
Re[2]: Размышления о типизаторе для Н2
От: catbert  
Дата: 31.05.11 16:54
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


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

WH>Наиболее яркий пример это ComputationExpressions. Там кроме стандартного использования через билдер могут быть и более тесно интегрированные решения. В частности array, list, enumerable, async,... Но об этом в другой раз.

WH>Теперь заведем вспомогательные предикаты.

WH>Эти и еще куча других предикатов будут в стандартной поставке.


WH>rewrite может генерировать недотипизированный АСТ.

WH>В этом случае производится локальная дотипизация.
WH>Если она выявила ошибки, то они считаются ошибками реализации и доводятся до пользователя с соответствующей пометкой.

А что тут, собственно, делается?
Re[3]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 16:58
Оценка:
Здравствуйте, catbert, Вы писали:

C>А что тут, собственно, делается?

Парсится и типизируется выражение if.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.05.11 17:00
Оценка:
Здравствуйте, WolfHound, Вы писали:

C>>А что тут, собственно, делается?

WH>Парсится и типизируется выражение if.

Ужас! Такую регрессию никто не оценит.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 17:25
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ужас! Такую регрессию никто не оценит.

Какую регрессию?
Все что добавилось по сравнению с твоим подходом это нормальные сообщения об ошибках.
В прочем если хочешь получать мутные сообщения в стиле Н1 можно все сильно сократить.
tast TypedIf : TypedExpression
for If
{
    ConvertibleTo(condition.ExpressionType, type(bool));
    Unify([trueExpression.ExpressionType, falseExpression.ExpressionType], ExpressionType);
}

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

Потом сравнивать на наномакросе не имеет смысла.
Подожди пока я до foreach дойду.

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

Короче это как статическая и динамическая типизация.
В случае с динамикой удается немного срезать углы но на чем-то что больше "Привет мир!" оно того не стоит.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.05.11 17:34
Оценка:
Здравствуйте, WolfHound, Вы писали:

Сразу оговорюсь, что оценка не за решение, а за то, что оно наконец то озвучено.

WH>
WH>abstract tast TypedExpression
WH>for Expression//Сообщаем системе какой узел ast типизировать данным tast
WH>{
WH>    ExpressionType : out Type;
WH>}

WH>tast TypedIf : TypedExpression
WH>for If
WH>{
WH>    trueType      = trueExpression.ExpressionType;//Локальные переменные.
WH>    falseType     = falseExpression.ExpressionType;//Для краткости.
WH>    conditionType = condition.ExpressionType;
    
WH>    ConvertibleTo(conditionType, type(bool))
WH>        @@@ $"Type of condition must be convertible to bool. But $(conditionType) not convertible to bool." condition.Location;

WH>    Unify([trueType, falseType], ExpressionType)
WH>        @@@ $"Typef of branches must be competible. $trueType and $falseType incompatible" this.Location;
WH>}
WH>rewrite//Понижение уровня языка.
WH>//В режиме ИДЕ никогда не выполняется.
WH>{
WH>    <[
WH>        match ($condition)
WH>        {
WH>            | true  => $trueExpression;
WH>            | false => $falseExpression;
WH>        }
WH>    ]>
WH>}
WH>

WH>После @@@ сообщение об ошибке которое показывается, если данное правило обламалось.

Здорово! Но какие проблемы (по сравнению с имеющимся подходом) решает эта куча кода? Я вижу только одну проблему — улучшение качества сообщений об ошибках.

Итак, у нас есть проблема — выражение condition должно иметь булев тип и если это не так, то мы должны выдать понятное конечному пользователю сообщение об ошибке.

Текущий путь — подстановка уточнения типа — приводит к не очень информативному сообщению.

Если убрать идеологические предрассудки, то решение этого должно быть простым, прямолинейным и удобным, а значит декларативным. Я бы описал этот макрос так:
macro If : Expression // по умолчанию типы параметров совпадающие с типом возвращаемого значения можно опускать
  syntax "if" "(" condition ")" trueExpr "else" falseExpr;
  // задаем условие на тип одного из параметров макроса
  requires condition.Type is bool otherwise Error(condition, "the expression cannot be converted to a 'bool'")
{
  <[
    match ($condition)
    {
      | true  => $trueExpr;
      | false => $falseExpr; // второе сообщение получается в результате типизации выражений в рамках match-а
    }
  ]>
}


Все эти навороты с rewrite, tast, for и т.п. — это никому не нужная пурга которая превратит написание макросов в сущий ад. Задачей компилятора является извлечь нужные данные и разбить работу на стадии (парсинг, типзиация, трансформация). Пользователю же важно чтобы он писал минимум кода и чтобы этот код был просто и осмыленнен.

WH>rewrite может генерировать недотипизированный АСТ.


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

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

WH>В этом случае производится локальная дотипизация.

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

Приведи, плиз, пример макроса которому нужна типизация на стадии SST. Только чтобы она действительно была нужна (чтобы без нее нельзя было обойтись).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 17:35
Оценка:
Здравствуйте, WolfHound, Вы писали:

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

WH>Твой подход на такое принципиально не способен.
Правда для foreach нужно еще кое что придумать.
Я ща if расширю:
Пример совершенно бредовый но просто демонстрация.
tast TypedStringIf : TypedExpression
for If
{
    trueType      = trueExpression.ExpressionType;//Локальные переменные.
    falseType     = falseExpression.ExpressionType;//Для краткости.
    conditionType = condition.ExpressionType;

    ConvertibleTo(conditionType, type(string))
        @@@ $"Type of condition must be convertible to string. But $conditionType not convertible to string." condition.Location;

    Unify([trueType, falseType], ExpressionType)
        @@@ $"Typef of branches must be competible. $trueType and $falseType incompatible" this.Location;
}
rewrite
{
    <[
        match ($condition)
        {
            | null | "" => $falseExpression;
            | _         => $trueExpression;
        }
    ]>
}
//задаем приоритет нашему расширению меньше чем стандартному if'у.
order TypedStringIf < TypedIf;

Теперь если в if передать строку то все будет работать.
Вот такая вот перегрузка макросов по типам параметров.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.05.11 17:37
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Теперь заведем вспомогательные предикаты.

WH>Эти и еще куча других предикатов будут в стандартной поставке.
WH>
WH>pred ConvertibleTo(from : Type, itemType : Type)
WH>mode (in, in) is semidet //Проверяет что один тип приводим к другому.
WH>mode (in, out) is multi  //При помощи бектрекинга перебирает все типы к которым можно привести данный.
WH>//multi по пому что тип как минимум можно привести к самому себе.
WH>//Так что хоть один результат да будет.
WH>//Реализацию выдумавать лень.

WH>//Пытается найти тип к которому можно привести все типы из списка.
WH>pred Unify(types : list[Type], result : Type)
WH>mode (in, out) is semidet
WH>


Вот это вот вообще не понятно. "semidet" так просто какое-то шифрование. Что это значит то?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 17:49
Оценка:
Здравствуйте, VladD2, Вы писали:

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

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


VD>Все эти навороты с rewrite, tast, for и т.п. — это никому не нужная пурга которая превратит написание макросов в сущий ад.

Ад это то, что сейчас и то, что предлагаешь ты.
Сейчас компилятор не предлагает никаких механизмов для создания чего-то сложнее, чем if.
В твоем решении их тоже нет.
Совсем.

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

Не сделает.

VD>Приведи, плиз, пример макроса которому нужна типизация на стадии SST.

foreach, lock, ?.,...

VD>Только чтобы она действительно была нужна (чтобы без нее нельзя было обойтись).

Нет таких. Ибо макросы полны по Тьюрингу и с помощью такойто матери можно сделать что угодно.
Но я не хочу кучу возни на ровном месте.
Вот тебе ярчайший пример твоего подхода:
  macro @?. (expr1, expr2)
  {
    def makeMemberAccess(loc, n) { PExpr.Member(loc,  <[ e1 ]>, Splicable.Name(loc, n)) }
    def makeComplation  (loc, n) { PExpr.Member(loc,  <[ e1 ]>, Splicable.HalfId(loc, n)) }
    def loc = expr2.Location;
    def e2 = 
      match (expr2)
      {
        | Ref(n)                    => makeMemberAccess(loc, n)
        | Call(Ref(n), parms)       => PExpr.Call(loc, makeMemberAccess(loc, n), parms)
        | Indexer(Ref(n), parms)    => PExpr.Indexer(loc, makeMemberAccess(loc, n), parms)
        | ToComplete(n)             => makeComplation(loc, n)
        | Call(ToComplete(n), _)    => makeComplation(loc, n)
        | Indexer(ToComplete(n), _) => makeMemberAccess(loc, n)
        | _ => Message.FatalError(expr2.Location, $"The expression of this ($(expr2.GetType())) type not supported with operator '?.'");
      };

    <[ 
      def e1 = $expr1;
      
      if (e1 == null)
        $(Typedtree.TExpr.DefaultValue() : typed)
      else
        $e2
    ]>
  }

У тебя в макросе автокомплит обрабатывается.
И ты ничего не предлагаешь, чтобы с этим бороться.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 17:50
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Вот это вот вообще не понятно. "semidet" так просто какое-то шифрование. Что это значит то?

Я ссылку на Mercury зачем дал?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.05.11 18:10
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>tast TypedIf : TypedExpression

WH>for If
WH>{
WH> trueType = trueExpression.ExpressionType;//Локальные переменные.
WH> falseType = falseExpression.ExpressionType;//Для краткости.
WH> conditionType = condition.ExpressionType;

WH> ConvertibleTo(conditionType, type(bool))

WH> @@@ $"Type of condition must be convertible to bool. But $(conditionType) not convertible to bool." condition.Location;

WH> Unify([trueType, falseType], ExpressionType)

WH> @@@ $"Typef of branches must be competible. $trueType and $falseType incompatible" this.Location;
WH>}

А как это дело вяжется с выводом типов? Ты еще не забыл, что типы невозможно вывести за один проход?

Вот даже если взять приведенный тобой (казалось бы простой!) код, то в нем уже заложена ошибка! Почему? Да потому, что некоторые языки (Немерл, Шарп, Васки...) используют неявное приведение типов. Ты тут используешь унификацию, но она не пройдет для всех случаев. Предположим что в trueExpression попало выражение типа A, а falseExpression типа B. Эти типы не унифицируются, так как у них нет общего предка за исключением object! Но для в типе B объявлен оператор неявного приведения типов (:>). Реальный код компилятора делает анализ всех возможных ситуаций и в случае необходимости меняет код получаемый в результате типизации. В данном случае для сочетания типов A и B будет добавлен вызов функции приведения типов (A к B).

Твой код всего лишь проверяет типы и накладывает ограничения. А надо менять код.

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

Как будет выглядит типизация вызова функции в условиях поддержки языком перегрузки? Мы это тоже заставим делать "пациента"?

WH>rewrite//Понижение уровня языка.

WH>//В режиме ИДЕ никогда не выполняется.

А что будем делать с linq который кроме как через такое переписываиние никак не реализуется? Ведь без переписывания мы не сможем вычислить правильны тип. Прочитай внимательно спецификацию C# 3.0:

26.7.1 Query expression translation

The C# 3.0 language does not specify the exact execution semantics of query expressions. Rather, C# 3.0 translates query expressions into invocations of methods that adhere to the query expression pattern. Specifically, query expressions are translated into invocations of methods named Where, Select, SelectMany, OrderBy, OrderByDescending, ThenBy, ThenByDescending, and GroupBy that are expected to have particular signatures and result types, as described in §26.7.2. These methods can be instance methods of the object being queried or extension methods that are external to the object, and they implement the actual execution of the query.

The translation from query expressions to method invocations is a syntactic mapping that occurs before any type binding or overload resolution has been performed. The translation is guaranteed to be syntactically correct, but it is not guaranteed to produce semantically correct C# code. Following translation of query expressions, the resulting method invocations are processed as regular method invocations, and this may in turn uncover errors, for example if the methods do not exist, if arguments have wrong types, or if the methods are generic and type inference fails.
The translation of query expressions is demonstrated through a series of examples in the following. A formal description of the translation rules is provided in a later section.


Таким образом твое предложение не проходит критики даже при не глубоком изучении.

Предлагаю пойти другим путем.

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

Во-вторых, если для "во-первых" приведены убедительные примеры, нужно подумать над необязательной типизацией SST. Ведь не сложно предоставить АПИ типизации которое может использоваться из макросов работающих по SST.

На мой взгляд, более реалистичной идеей является идея декларативного указания компилятору необходимости типизировать отдельные части SST путем их раскрытия в AST и стандартной типизации. Вычисленные таким образом типы могут помещаться в SST (вместе со ссылками на произведенные AST и TAST) и могут использоваться внутри макросов.

В этой схеме макрос делится на две стадии. При парсинге всегда порождается SST. SST порожденное макросом закладывается в общее дерево проекта. При этом ветки SST помещается в специальные ветки-обертки AST. Когда типизиатор доходит до типизации таких веток, запускается код макроса (тот что находится внутри тела). При этом анализируются декларативные предикаты (вроде requires приведенный мною здесь) и, если надо, производится предварительная типизация отдельных параметров макросов. Это может изменять порядок типизации.

В общем, моя основная мысль очень проста. Вместо того чтобы выдумывать какие-то новые схемы типизации (не выдерживающие критики) лучше осмыслить ошибки текущего дизайна и сделать новый дизайн на основе старого, но без ошибок. Старый дизайн показал свою работоспособность на практике. Его проблемы — это проблемы реализации. Их не трудно обойти.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.05.11 18:11
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>Вот это вот вообще не понятно. "semidet" так просто какое-то шифрование. Что это значит то?

WH>Я ссылку на Mercury зачем дал?

Ща мы обсуждая твое сообщение за одно быстренько изучим все что касается Меркури. Это птичий язык который на фиг не уперся. И если ты его приводишь, то будь добр пояснять. Иначе тебя никто не поймет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.05.11 18:32
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


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

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

Какой синтаксис? Это вот эта гора непонятных наворотов — это синтаксис? Ау! Меня не слышат?
То что ты привел — никуда не годится.

WH>Сахара я могу насыпать не меньше твоего.


Напиши. Результат должен быть не длиннее, и не сложнее моего. ОК?

VD>>Все эти навороты с rewrite, tast, for и т.п. — это никому не нужная пурга которая превратит написание макросов в сущий ад.

WH>Ад это то, что сейчас и то, что предлагаешь ты.

Да? Ну, тогда тебе не составит труда конструктивно раскритиковать мое решение.

WH>Сейчас компилятор не предлагает никаких механизмов для создания чего-то сложнее, чем if.


Мы не ведем разговор про сейчас.

WH>В твоем решении их тоже нет.


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

WH>Совсем.


Аргументы?

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

WH>Не сделает.

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

VD>>Приведи, плиз, пример макроса которому нужна типизация на стадии SST.

WH>foreach, lock, ?.,...

Не, не. Меня не интересует перечисление. Меня интересует псевдокод реализации с комментариями. Реализацию foreach я тебе уже приводил. В прочем, вот она еще раз:
macro module Nemerle
{
  macro ForEach : Ast.Expression
    syntax: "foreach" "(" pattern "in" collection ")" body
      where: pattern    = Ast.PatternWithGuard,
             collection = Ast.Expression,
             body       = Ast.Expression;
    require: IsTyped(collection) // требуем чтобы перед вызовом тела макроса был типизирован параметр collection
  {
    match (GetKind(collection.Type))
    {
      | TypeKind.Array        => IterateByArrayImpl(pattern, collection, body)
      | TypeKind.List         => IterateByListImpl(pattern, collection, body)
      | TypeKind.IEnumarableT => IterateByIEnumarableTImpl(pattern, collection, body)
      | TypeKind.IEnumarable  => IterateByIEnumarableImpl(pattern, collection, body)
      | _                     => TryIterateByEnumaratorPatternImpl(pattern, collection, body)
    }
  }

  IterateByArrayImpl(pattern : Ast.PatternWithGuard, collection : Ast.Expression, body : Ast.Expression) : Ast.Expression
  {
    match (pattern)
    {
      | <[ $(x : name) ]> => // pattern - это просто имя переменной (простой случай)
        <[ Nemerle: // указываем, что квази-цитата задается в грамматике Nemerle. 
           def loop(i : int, ary) : void
           {
             when (i < ary.Lenght)
             {
               def $x = ary[i];
               $body;
               loop(i + 1, ary)
             }
           } 

           loop(0, $collection);
        ]>
      ... // случаи с применением паттерн-матчинга опущены
    }
  }
  ...
}

Детали можно найти по ссылке сверху.
А вот так вот в моем варианте будет выглядить макрос lock:
  macro @lock : Ast.Expression
    syntax "lock" "(" lockOnExpr ")" body
    require: IsTyped(lockOnExpr)
  {
    if (lockOnTExpr.Type.IsValueType)
      Error (lockOnExpr, $"`$(lockOnTExpr.Type)' is not a reference type as required by the lock expression")
    else
      <[
        def toLock = $(lockOnTExpr : typed);
        System.Threading.Monitor.Enter(toLock);
        try { $body }
        finally { System.Threading.Monitor.Exit(toLock); }
      ]>
  }


Приведи свои реализации для них, тогда и обсудим.

VD>>Только чтобы она действительно была нужна (чтобы без нее нельзя было обойтись).

WH>Нет таких. Ибо макросы полны по Тьюрингу и с помощью такойто матери можно сделать что угодно.

Не, ну, достаточно примера который просто показал бы, что твое решение существенно проще и/или короче.

WH>Но я не хочу кучу возни на ровном месте.

WH>Вот тебе ярчайший пример твоего подхода:

В этом макросе нет ни грамма типизации. Ни грамма! Проблема имеющайся в этом коде заключается в том, что квази-цтирование теряет информацию о местопложении и месте кмплита (автодополнения введенного слова). Если оные проблемы удастся избежать, то код будет совсем простым.

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

WH>У тебя в макросе автокомплит обрабатывается.

WH>И ты ничего не предлагаешь, чтобы с этим бороться.

Может не надо демагогии то?

Когда проектировался Н1 о вещах вроде комплейшона и тем более об IDE никто не думал. Потому эта задница и нарисовалась.

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

Если мы хотим получить качественное решение, то надо их искать (предлагать), а не аппелировать черт знает к чему.

Вот ты затронул тему протаскивания локешонов и местоположения комплита. Так покажи как твое решение будет их решать. Это будет конструктивно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.05.11 18:38
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Правда для foreach нужно еще кое что придумать.


Придумай и покажи. Я уже показал.

Пример с if в два раза сложнее и длиннее предложенного мной. Пока что счет 1 : 0 в пользу моего решения. Допускаю (хотя и сомневаюсь), что дело в простоте макроса. Возможно макросы по сложнее у тебя удадутся по лучше. ОК, ждем.

WH>Я ща if расширю:

WH>Пример совершенно бредовый но просто демонстрация.
WH>
WH>tast TypedStringIf : TypedExpression
WH>for If
WH>{
WH>    trueType      = trueExpression.ExpressionType;//Локальные переменные.
WH>    falseType     = falseExpression.ExpressionType;//Для краткости.
WH>    conditionType = condition.ExpressionType;

WH>    ConvertibleTo(conditionType, type(string))
WH>        @@@ $"Type of condition must be convertible to string. But $conditionType not convertible to string." condition.Location;

WH>    Unify([trueType, falseType], ExpressionType)
WH>        @@@ $"Typef of branches must be competible. $trueType and $falseType incompatible" this.Location;
WH>}
WH>rewrite
WH>{
WH>    <[
WH>        match ($condition)
WH>        {
WH>            | null | "" => $falseExpression;
WH>            | _         => $trueExpression;
WH>        }
WH>    ]>
WH>}
WH>//задаем приоритет нашему расширению меньше чем стандартному if'у.
WH>order TypedStringIf < TypedIf;
WH>

WH>Теперь если в if передать строку то все будет работать.
WH>Вот такая вот перегрузка макросов по типам параметров.

Пример похоже настолько бредовый, что я него не понял. Что он добивается то?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 18:58
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ща мы обсуждая твое сообщение за одно быстренько изучим все что касается Меркури. Это птичий язык который на фиг не уперся. И если ты его приводишь, то будь добр пояснять. Иначе тебя никто не поймет.

Изучить меркури в любом случае полезно.
Это очень хороший язык.
http://www.mercury.csse.unimelb.edu.au/information/doc-release/mercury_ref/Determinism-categories.html#Determinism-categories
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 18:58
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А как это дело вяжется с выводом типов? Ты еще не забыл, что типы невозможно вывести за один проход?

Отлично.

VD>Вот даже если взять приведенный тобой (казалось бы простой!) код, то в нем уже заложена ошибка!

Ох.
Ты еще к запятым начни цепляться.

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

Вот это все и нужно спрятать за формальную систему.
Ибо то, что есть сейчас это смерть мозгу.

VD>Как будет выглядит типизация вызова функции в условиях поддержки языком перегрузки? Мы это тоже заставим делать "пациента"?

Оно будет написано один раз и "пациент" если ему оно понадобиться сможет это использовать.
Хотя зачем ему это может понадобиться не ясно.

VD>А что будем делать с linq который кроме как через такое переписываиние никак не реализуется? Ведь без переписывания мы не сможем вычислить правильны тип. Прочитай внимательно спецификацию C# 3.0:

Хватит уже эту страшилку в сотый раз повторять.
Это решаемая задача.
Я просто думаю, как это сделать получше.

VD>Таким образом твое предложение не проходит критики даже при не глубоком изучении.

Особенно учитывая то, что ты ни слова из написанного не понял...

VD>Во-первых, нужно обосновать необходимость типизации SST.

Да ты на свой ?. посмотри.
Это же просто феерия.
Ты пойми никто кроме тебя его не напишет.
НИКТО!
Ибо никто не понимает что за возня там с автокомплитом.

VD>Для этого нужно привести хотя бы один пример где типизация по SST дает зримое преимущество над аналогичной реализации без типизации SST.

foreach, lock,...
А такие макросы как PegGrammar вообще без этого сделать нельзя.
Совсем.
Никак.
Сейчас SST типизируется руками.
Информация для IDE о том, что к чему относиться задается руками.
Автокомплита нет и не предвидеться.

VD>Чем больше я над этим думаю, тем чаще прихожу к выводу, что таких примеров попросту нет. Возможно, я не прав, но хотелось бы увидеть это на реальном примере.

Я тебя уже заколебался в них носом тыкать.
А ты все нету да нету.

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

Ты мне тоже самое говорил, когда я сидел и ломал мозг на тему скрещивания ПЕГа с Праттом.
А через год ты мне начнёшь доказывать что это ты придумал SST типизировать
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 18:59
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Пример похоже настолько бредовый, что я него не понял. Что он добивается то?

Чтобы string можно было в if засунуть.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Размышления о типизаторе для Н2
От: catbert  
Дата: 31.05.11 19:09
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


C>>А что тут, собственно, делается?

WH>Парсится и типизируется выражение if.

А почему все так сложно по сравнению с Н1? Не то что бы я критично настроен, но зачем вообще отдельная типизация для всех конструкций, кроме встроенных в язык?
Re[5]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 19:16
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Да? Ну, тогда тебе не составит труда конструктивно раскритиковать мое решение.

Ты про ту гору нерасширяемого императива, который наворачивается на императивный типизатор в котором никто ничего не понимает?


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

Мой код проблем не создает.

VD>Не, не. Меня не интересует перечисление. Меня интересует псевдокод реализации с комментариями. Реализацию foreach я тебе уже приводил. В прочем, вот она еще раз:

1)Твой код не расширяем.
Попробуй добавить IterateByMyCollectionImpl без изменения макроса foreach.
2)Твой код требует чтобы тип коллекции был извествен до того как начнет работать макра.
А что делать, если тип выводиться на основе тела цикла?

VD>То же как типизировать этот код ровным счетом никак не повлияет на наличие в нем "кучу возни на ровном месте".

Повлияет. Никакой возни не будет.
Совсем не будет.

VD>Эти проблемы, конечно же, нужно решать. Но я от тебя не слышу предложений по решению этих проблем. Зато вижу апелляцию к вещам не относящимся к делу.

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

VD>Если мы хотим получить качественное решение, то надо их искать (предлагать), а не аппелировать черт знает к чему.

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

VD>Вот ты затронул тему протаскивания локешонов и местоположения комплита. Так покажи как твое решение будет их решать. Это будет конструктивно.

Т.к. у меня нет трансформаций АСТ во время работы ИДЕ и вся типизация описана декларативно у меня такой проблемы просто не возникнет.
Кодогенератор просто сгенерирует весь нужный код.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Размышления о типизаторе для Н2
От: catbert  
Дата: 31.05.11 19:19
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>3)Собственно язык описания правил вывода типов.

WH>Мои мысли в данный момент крутяться вокруг Mercury.
WH>Несколько упрощенный Mercury будет отличной основой для создания языка описания типизации.
WH>Я выбрал Mercury ибо типизация это поиск с откатами. Как раз то вокруг чего построен этот язык.

+1

WH>Пролог пошёл лесом, ибо Mercury это пролог сделанный правильно.


в чем именно, в контексте вывода типов, Меркюри лучше Пролога?
Re[2]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 19:25
Оценка:
Здравствуйте, catbert, Вы писали:

C>в чем именно, в контексте вывода типов, Меркюри лучше Пролога?

Скорость работы, статическая типизация и отсутствие императива.
Короче в прологе нет ничего, что было бы лучше, чем в меркури.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Размышления о типизаторе для Н2
От: Silver_S Ниоткуда  
Дата: 31.05.11 19:30
Оценка:
Здравствуйте, VladD2, Вы писали:

WH>>pred ConvertibleTo(from : Type, itemType : Type)

WH>>mode (in, in) is semidet //Проверяет что один тип приводим к другому.
WH>>mode (in, out) is multi //При помощи бектрекинга перебирает все типы к которым можно привести данный.

VD>Вот это вот вообще не понятно. "semidet" так просто какое-то шифрование. Что это значит то?


Выходит что-то типа nullable, или bool

either have no solutions or have one solution, then that mode is semideterministic(semidet);


Похоже 2 перегрузки, первая принимает 2 параметра и возвращает true/false,
вторая принимает 1 параметр и возвращает список.
Re[5]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 19:31
Оценка:
Здравствуйте, catbert, Вы писали:

C>А почему все так сложно по сравнению с Н1?

1)Не так уж и сложно.
2)Можно насыпать сахару.
3)На макрах побольше Н1 сольет даже без сахара.

C>Не то что бы я критично настроен, но зачем вообще отдельная типизация для всех конструкций, кроме встроенных в язык?

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

Макросам типа foreach необходима информация о типах для того чтобы сгенерировать код.

И в целом это просто решит все проблемы с автокомплитом (включаяя сложные ДСЛ), навигацией, хинтами и сделает реализацию рефакторингов тривиальной.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Размышления о типизаторе для Н2
От: catbert  
Дата: 31.05.11 19:36
Оценка:
Здравствуйте, Silver_S, Вы писали:

S_S>Выходит что-то типа nullable, или bool

S_S>

S_S>either have no solutions or have one solution, then that mode is semideterministic(semidet);


В мире пролога/меркюри это означает, что после нахождения первого решения, остальные искаться уже не будут.
Re[5]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 31.05.11 19:48
Оценка:
Здравствуйте, catbert, Вы писали:

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

Нет. В мире меркури это означает, что есть ровно 0 или 1 решение.
Остальные решения искаться не будут по тому что их нет.
Совсем нет.
Гарантированно компилятором.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 14:33
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Какую регрессию?


Куча невнятного кода которого раньше не было нужды писать — это регрессия.

WH>Все что добавилось по сравнению с твоим подходом это нормальные сообщения об ошибках.


А это откровенная неправда. Я тебе показал решение которое обеспечивает качественное сообщение об ошибке.

WH>В прочем если хочешь получать мутные сообщения в стиле Н1 можно все сильно сократить.

WH>
WH>tast TypedIf : TypedExpression
WH>for If
WH>{
WH>    ConvertibleTo(condition.ExpressionType, type(bool));
WH>    Unify([trueExpression.ExpressionType, falseExpression.ExpressionType], ExpressionType);
WH>}
WH>


Я вообще не хочу видеть этого мутного кода. А вот сообщения действительно стоило бы улучшить. Но это можно сделать и без лишних действий.

WH>Или можно сделать еще веселее позволить типизироваться по переписанному коду и затаскивать типы от туда.


По сути я это и предлагаю сделать. Возможно ты меня не понял до конца.
Только я предлагаю не заниматься ручной типизации без насущной необходимости. Лучше заставить компилятор выполнять типизацию по требованию (выражаемому в декларативной манере).

WH>Правда, сообщения об ошибках будут такие же мутные как сейчас.


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

WH>А хинты проясняющие ситуацию придется хардкодить в ядро компилятора...


Ни в коем разе! Это точно не решение.

WH>Потом сравнивать на наномакросе не имеет смысла.

WH>Подожди пока я до foreach дойду.

Давно жду.

WH>Вот тогда ты и увидишь насколько твой подход императивен и не расширяем.

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

foreach был расширяем в Н1. Есть, например, версия с otherwise. Так что тут ты Америку не открыл.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 15:15
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>Да? Ну, тогда тебе не составит труда конструктивно раскритиковать мое решение.

WH>Ты про ту гору нерасширяемого императива, который наворачивается на императивный типизатор в котором никто ничего не понимает?
WH>

Я демагогию игнорирую.

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

WH>Мой код проблем не создает.

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

VD>>Не, не. Меня не интересует перечисление. Меня интересует псевдокод реализации с комментариями. Реализацию foreach я тебе уже приводил. В прочем, вот она еще раз:

WH>1)Твой код не расширяем.
WH>Попробуй добавить IterateByMyCollectionImpl без изменения макроса foreach.

Хорошая мысль! Только ради нее стоило вести эту беседу!

Согласен, было бы хорошо иметь возможность перегружать макросы по типам. Это увеличило бы расширяемость. Но это опять таки можно сделать на основе декларации намерений. Так вместо одного макроса с:
    require: IsTyped(collection) // требуем чтобы перед вызовом тела макроса был типизирован параметр collection

и ручным разбором типов коллекции можно было ввести несколько макросов с одним и тем же синтаксисом, но разными "require". Например, так:
  macro ForEachOnArray : Ast.Expression
    syntax: "foreach" "(" pattern "in" collection ")" body
      where: pattern    = Ast.PatternWithGuard,
             collection = Ast.Expression,
             body       = Ast.Expression;
    require: GetKind(collection.Type) == TypeKind.Array
  {
    <[ /* реализация для массива */ ]>
  }

  macro ForEachOnArray : Ast.Expression
    syntax: "foreach" "(" pattern "in" collection ")" body
      where: pattern    = Ast.PatternWithGuard,
             collection = Ast.Expression,
             body       = Ast.Expression;
    require: GetKind(collection.Type) == TypeKind.IEnumarableT
  {
    <[ /* реализация для IEnumarable[T] */ ]>
  }
...


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

WH>2)Твой код требует чтобы тип коллекции был извествен до того как начнет работать макра.


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

Обрати внимание на сказанное выше. От типа коллекции зависит то какой код будет поражден. И это же влияет на то как он будет типизирован (и окончится ли типизация успехом). По сему этот макрос требует предварительной типизации своего параметра "collection" и требует, чтобы остальные параметры до выведения типа для collection не были типизированы.

WH>А что делать, если тип выводиться на основе тела цикла?


Это невозможно. Тело зависит от типа коллекции. Сейчас делается именно так, и как видишь, foreach работает замечательно.

VD>>То же как типизировать этот код ровным счетом никак не повлияет на наличие в нем "кучу возни на ровном месте".

WH>Повлияет. Никакой возни не будет.

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

Если хочешь обсудить проблему комплешона и протаскивания локешонов, заводи отдельную тему. Тут это офтоп.

VD>>Эти проблемы, конечно же, нужно решать. Но я от тебя не слышу предложений по решению этих проблем. Зато вижу апелляцию к вещам не относящимся к делу.

WH>Так если вся типизация будет декларативно описана, то эти проблемы просто не возникнут.

Да, ну? Во как? Вкратце — это не так. Для комплешона нужна отдельная обработка. Необходимость прибегать к использованю паттерн-матчинга по АСТ (без квази-цитирования, КЦ) связана с тем, что при преобразованиях с использованием КЦ теряются локешоны и IDE не может работать корректно. Вот простой пример:
def expr2 = 
  match (expr1)
  {
    | <[ $call(..$parms) ]> => <[ $call(..$parms) ]>
    ...
  };

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

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

WH>В движке будет вся информация.


Опять пустые слова, а нужны объяснения.

WH>Пользователь вообще ничего про IDE во время разработки макросов знать не будет.


Хотелось бы чтобы так было. Но это снова похоже на притчу про самолеты.

WH>Ну разве что если захочет написать рефакторинг.


Жду внятных разъяснений.

VD>>Вот ты затронул тему протаскивания локешонов и местоположения комплита. Так покажи как твое решение будет их решать. Это будет конструктивно.

WH>Т.к. у меня нет трансформаций АСТ во время работы ИДЕ и вся типизация описана декларативно у меня такой проблемы просто не возникнет.

Гы-гы. Твоя схема вообще не жизнеспособна. Как только ты начал хоть немножко задумываться о реальности, то у тебя сразу появились какие-то там transform и т.п.

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

WH>Кодогенератор просто сгенерирует весь нужный код.


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

Плюс огромный минус твой схемы заключается в том, что по сути ты предлагаешь переложить типизацию на плечи тех кто пишет макросы. Да и макросы ты, похоже, хочешь уничтожить, заменив их каким-то средством создания классических компиляторов (где пользователю не предлагается абстракции вроде макросов, а предлагается влезать в разные стадии компиляции).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 15:19
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


VD>>Ща мы обсуждая твое сообщение за одно быстренько изучим все что касается Меркури. Это птичий язык который на фиг не уперся. И если ты его приводишь, то будь добр пояснять. Иначе тебя никто не поймет.

WH>Изучить меркури в любом случае полезно.

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

WH>Это очень хороший язык.

WH>http://www.mercury.csse.unimelb.edu.au/information/doc-release/mercury_ref/Determinism-categories.html#Determinism-categories

Охотно верю. Буду очень признателен, если ты (или кто-то еще) опишет что нужно сделать чтобы сделать первые шаги.

Но в контексте данной темы апелляция к Меркури не канает. Это слишком большой барьер. Так что опиши суть этих функций. А еще лучше дай им разумные имена. Чтобы из них была ясна их суть. То что меркури писали очередные ученые которым плевать на то что их язык никто не использует никак не оправдывает тебя.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 15:40
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>А как это дело вяжется с выводом типов? Ты еще не забыл, что типы невозможно вывести за один проход?

WH>Отлично.

В лес, такие "аргументы".

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

WH>Вот это все и нужно спрятать за формальную систему.
WH>Ибо то, что есть сейчас это смерть мозгу.

Ага. Надо. Но ты предлагаешь обратный процесс. Ты предлагаешь порвать мозг еще сильнее.

VD>>Как будет выглядит типизация вызова функции в условиях поддержки языком перегрузки? Мы это тоже заставим делать "пациента"?

WH>Оно будет написано один раз и "пациент" если ему оно понадобиться сможет это использовать.
WH>Хотя зачем ему это может понадобиться не ясно.

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

VD>>А что будем делать с linq который кроме как через такое переписываиние никак не реализуется? Ведь без переписывания мы не сможем вычислить правильны тип. Прочитай внимательно спецификацию C# 3.0:

WH>Хватит уже эту страшилку в сотый раз повторять.
WH>Это решаемая задача.
WH>Я просто думаю, как это сделать получше.

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

VD>>Таким образом твое предложение не проходит критики даже при не глубоком изучении.

WH>Особенно учитывая то, что ты ни слова из написанного не понял...

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

VD>>Во-первых, нужно обосновать необходимость типизации SST.

WH>Да ты на свой ?. посмотри.

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

VD>>Для этого нужно привести хотя бы один пример где типизация по SST дает зримое преимущество над аналогичной реализации без типизации SST.

WH>foreach, lock,...

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

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

WH>А такие макросы как PegGrammar вообще без этого сделать нельзя.

WH>Совсем.
WH>Никак.
WH>Сейчас SST типизируется руками.
WH>Информация для IDE о том, что к чему относиться задается руками.

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

WH>Автокомплита нет и не предвидеться.


Дык, не продумано было. Вот и нет. Продумаем — будет. Не думаешь же ты, что от того что ты сотрясаешь воздух что-то изменится?

Я согласен, что отсутствие комплита для макросов вроде PegGrammar — это не доработка. Разумно было бы предоставить какие-то средства для организации интеллисенса для подобных ДСЛ-ей. Так же согласен, что гипотетически, можно быть полезно производить типизацию по SST. Но все это можно прекрасно вписать в модель допускающую трасформацию нетипизированного AST.

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

VD>>Чем больше я над этим думаю, тем чаще прихожу к выводу, что таких примеров попросту нет. Возможно, я не прав, но хотелось бы увидеть это на реальном примере.

WH>Я тебя уже заколебался в них носом тыкать.

Ты ни одного примера не привел. Ты все воздух сотрясаешь. И меня это уже начало заколебывать. Пожалуй что я перестану отвечать на твои выпады до тех пор пока не увижу от тебя полноценного описания реализации макросов foreach, linq и PegGremmar. Под полноценным я понимаю описание с псевдокодом из которого можно увидеть механизмы работы, а не демагогию вроде "заколебался в них носом тыкать" и перечисление названий.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 15:48
Оценка:
Здравствуйте, Silver_S, Вы писали:

WH>>>pred ConvertibleTo(from : Type, itemType : Type)

WH>>>mode (in, in) is semidet //Проверяет что один тип приводим к другому.
WH>>>mode (in, out) is multi //При помощи бектрекинга перебирает все типы к которым можно привести данный.

VD>>Вот это вот вообще не понятно. "semidet" так просто какое-то шифрование. Что это значит то?


S_S>Выходит что-то типа nullable, или bool

S_S>

S_S>either have no solutions or have one solution, then that mode is semideterministic(semidet);


S_S>Похоже 2 перегрузки, первая принимает 2 параметра и возвращает true/false,

S_S>вторая принимает 1 параметр и возвращает список.

Вот, здорово! Это мы теперь от людей, которые хотят макрос написать, будем требовать изучения разной загробной хрени вроде знания что такое "semideterministic". А чтобы они уж точно макросы не начали писать еще и зашифруем это название в "semidet". Супер!

Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 16:44
Оценка:
Здравствуйте, catbert, Вы писали:

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


Отсечение что ли? И зачем это так шифровать?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 16:50
Оценка:
WH>>Пролог пошёл лесом, ибо Mercury это пролог сделанный правильно.

C>в чем именно, в контексте вывода типов, Меркюри лучше Пролога?


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

Вот только на фиг он для вывода типов не нужен. Это перебор. Тут нужен логический ДСЛ. В Н1 используется класс — Solver. Это своего рода микро Меркури. Он поддерживает нужную для вывода типов унификацию.

Можно развить это дело. С одной стороны кроме класса можно было бы завести ДСЛ. С другой кроме подсистему унификации так же было бы разумно завести подсистему описания правил вывода типов и их "решатель". Это позволило бы устранить (или хотя бы уменьшить) объем "рукопашного" кода типизации — основного источника ошибок.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 01.06.11 17:01
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это типа такой странный способ приведения к булеву типу когда null интерпретируется как false?

VD>Пример более чем станный. С этим люди боролись, боролись, а ты решил это как преимущество показать.
Это был всеголишь пример перегрузки макры по типу.
А ты тут разводишь демагогию цепляясь ко всему подряд
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 01.06.11 17:01
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А это откровенная неправда. Я тебе показал решение которое обеспечивает качественное сообщение об ошибке.

Которое мое вид в профиль.

VD>Я вообще не хочу видеть этого мутного кода. А вот сообщения действительно стоило бы улучшить. Но это можно сделать и без лишних действий.

Но сам предлагаешь тоже самое но с другим синтаксом

WH>>А хинты проясняющие ситуацию придется хардкодить в ядро компилятора...

VD>Ни в коем разе! Это точно не решение.
Так происходит сейчас.
И ты не предлагаешь никаких механизмов чтобы этого избежать.

VD>foreach был расширяем в Н1. Есть, например, версия с otherwise. Так что тут ты Америку не открыл.

Ты бы почитал о чем я говорю.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 01.06.11 17:01
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ага. Надо. Но ты предлагаешь обратный процесс. Ты предлагаешь порвать мозг еще сильнее.

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

VD>Очередной раз демагогией занимаешься?

VD>ОК, в очередной раз отвечу тебе конструктивно — этот вопрос никак не связан с обсуждаемым. Вникни в проблему и сам это поймешь.
Сам вникни.
Это происходит из-за фундаментально ущербного подхода, который не может не терять информацию.
Я же предлагаю подход, который ее терять не будет.
Никогда.
Как следствие проблем, которые ты тут описываешь, просто не будет.

VD>Дык, не продумано было. Вот и нет. Продумаем — будет.

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

VD>Не думаешь же ты, что от того что ты сотрясаешь воздух что-то изменится?

Воздух тут трясешь ты.
Я пытаюсь придумать решение проблем.

VD>Более того, я уверен, что перекладывание типизации на плечи писателей макросов в общем случае является ошибкой дизайна. Это усложнит написание макросов и сделает их еще менее доступными для простых смертных. Если сегодня писать макросы мешает кривой API и сложные паттерны, то в твоей схеме появится еще и необходимость типизации там где раньше в ней не было необходимости. Это же так очевидно!

Я еще давно сказал, что простые макросы станут чуть сложнее.
За то сложные упростятся многократно.
И у них будет работать автокомплит, подсветка, навигация, рефакторинг,... из коробки.
Твой подход это никогда не обеспечит.
Заколебешься частные случаи отлавливать.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 01.06.11 17:01
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Я демагогию игнорирую.

И сам ей постоянно пользуешься.

VD>Твой код сложный и слишком похож на тот анекдот где самолеты на границе переворачиваются и падают. Он не учитывает кучи нюансов.

Это блин набросок.

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

Ну то есть создать неоднозначный АСТ?
Замечательное решение.

VD>Ага! И это то что нужно этой макре. Причем типизировать какие-либо другие параметры нельзя, так как до подстановки конечного кода они не смогут успешно стипизироваться. Именно так сегодня и реализован макрос foreach. И никак иначе ты его не сможешь реализовать.

Ты в твоем подходе не сможешь.
А я смогу.

VD>Это невозможно. Тело зависит от типа коллекции. Сейчас делается именно так, и как видишь, foreach работает замечательно.

Возможно.
Нужно только отступить от идеологии Н1.

VD>Если хочешь обсудить проблему комплешона и протаскивания локешонов, заводи отдельную тему. Тут это офтоп.

Нет. Не оффтоп.
Это взаимосвязанные темы.
И одно в отрыве от другого ты качественно не сделаешь.

VD>Да, ну? Во как? Вкратце — это не так. Для комплешона нужна отдельная обработка. Необходимость прибегать к использованю паттерн-матчинга по АСТ (без квази-цитирования, КЦ) связана с тем, что при преобразованиях с использованием КЦ теряются локешоны и IDE не может работать корректно. Вот простой пример:

Ты говоришь о проблемах в Н1.
А я говорю про принципиально иной подход.
В моем подходе не нужно трансформировать АСТ для типизации.
Как следствие все эти проблемы просто никогда не возникнут.

VD>Опять пустые слова, а нужны объяснения.

Как тебе еще объяснить?
Ты все пропускаешь через стереотипы Н1.
И даже не пытаешься понять сказанное.

Нет трансформации АСТ -> Нет потери информации -> Нет проблем с автокомплитом.

Сколько раз еще тебе повторить эту простую цепочку?

WH>>Пользователь вообще ничего про IDE во время разработки макросов знать не будет.

VD>Хотелось бы чтобы так было. Но это снова похоже на притчу про самолеты.
А ты просто вместо того чтобы кричать что все это глупости и не возможно в принципе попробуй понять о чем я говорю.

VD>Жду внятных разъяснений.

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

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

Нет у меня никаких transform.
В моей схеме все трансформации происходят после типизации!!!

VD>Кроме того такие вещи как специальные ветви АСТ для комплита и их же специальная обработка при типизации никуда не исчезнут. Просто они из универсального кода написанного профессионалами переползут в прикладной код макросов. И вот это уже будет печально.

Это происходит в ТВОЕЙ схеме!!!
В моей схеме этого не будет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 17:16
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>А это откровенная неправда. Я тебе показал решение которое обеспечивает качественное сообщение об ошибке.

WH>Которое мое вид в профиль.

VD>>Я вообще не хочу видеть этого мутного кода. А вот сообщения действительно стоило бы улучшить. Но это можно сделать и без лишних действий.

WH>Но сам предлагаешь тоже самое но с другим синтаксом

А, ну, вот у нас уже прогресс. Когда ты принимаешь мои предложения они у тебя сразу же становятся "твоими, вид в профиль".

Дык я не гордый. Мня авторство идей не тешит. Можешь считать их своими, но с другим синтаксисом .

Для меня главное, что этот самый другой синтаксис не сложнее того что есть в Н1 и может быть реализован в рамках модели SST -> AST -> TAST, которая явно работоспособна (так как частично проверена на практике) и дает такие важные преимущества как:
1. Возможность не грузить без надобности писателей макросов вопросами типизации.
2. Возможность осуществлять нетипизированные реобразования.
3. Возможность реализации единых алгоритмов IDE и компилятора для разных языков.

WH>>>А хинты проясняющие ситуацию придется хардкодить в ядро компилятора...

VD>>Ни в коем разе! Это точно не решение.
WH>Так происходит сейчас.

Вот уж что меня не трогает, так это то что происходит сейчас. Я не собираюсь повторять ошибки.

WH>И ты не предлагаешь никаких механизмов чтобы этого избежать.


Лож. Я их продемонстрировал.

VD>>foreach был расширяем в Н1. Есть, например, версия с otherwise. Так что тут ты Америку не открыл.

WH> Ты бы почитал о чем я говорю.

Ты пока что своей версии не показал. Так что говорить не о чем. Твое замечание по поводу перегрузки на основе типов я принял и опять же предложил решение. С ним есть какие-то проблемы?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 17:19
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>Ага. Надо. Но ты предлагаешь обратный процесс. Ты предлагаешь порвать мозг еще сильнее.

WH>Я предлагаю систему, которую можно понять.

Я уже говорил тебе, что не буду ничего обсуждать до предъявления тобой прсевдокода реализаций foreach, linq и PegGrammar с объяснением того что дает такая реализация.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 17:20
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>Я демагогию игнорирую.

WH>И сам ей постоянно пользуешься.

Я уже говорил тебе, что не буду ничего обсуждать до предъявления тобой прсевдокода реализаций foreach, linq и PegGrammar с объяснением того что дает такая реализация.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Размышления о типизаторе для Н2
От: Аноним  
Дата: 01.06.11 17:32
Оценка:
Здравствуйте, VladD2, Вы писали:

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


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


VD>Отсечение что ли? И зачем это так шифровать?


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

Если же укажешь его для многозначной функции то результатом будет первое решение, но это не верный подход с точки зрения языка.
Re[9]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 01.06.11 17:37
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А, ну, вот у нас уже прогресс. Когда ты принимаешь мои предложения они у тебя сразу же становятся "твоими, вид в профиль".

Ну, то есть сдираем то что я написал.
Меняем синтаксис и объявляем своим.
Причем передрал криво.
Про второе сообщение об ошибке "забыл" и сэкономил одну строчку.
Вот всегда ты так.

VD>1. Возможность не грузить без надобности писателей макросов вопросами типизации.

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

VD>2. Возможность осуществлять нетипизированные реобразования.

Которые сами по себе никому не нужны.

VD>3. Возможность реализации единых алгоритмов IDE и компилятора для разных языков.

ЛОЖ!
Ты на свой ?. посмотри.
А в PegGrammar так вообще кучу кода на эту тему.
Причем вопросы автокомплита не решены никак.

VD>Вот уж что меня не трогает, так это то что происходит сейчас. Я не собираюсь повторять ошибки.

Ты делаешь РОВНО ТУЖЕ МОДЕЛЬ ТИПИЗАЦИИ!!!
Ты решишь несколько частных случаев, но проблемы будут возникать раз за разом.
Ибо нужно не частные случаи давить, а делать общее решение.

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

Масса.
Начиная с того что не ясно где и как хранить неоднозначный АСТ.
Но все что ты осилил это:

Я уже говорил тебе, что не буду ничего обсуждать до предъявления тобой прсевдокода реализаций foreach, linq и PegGrammar с объяснением того что дает такая реализация.

... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 18:23
Оценка:
Здравствуйте, WolfHound, Вы писали:

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

WH>Ну то есть создать неоднозначный АСТ?

SST может быть единым. Он же по одной и той же грамматике строится. А вот то какой из макросов вызовется для его обработки будет определяться предикатами (ака require). Единственный вопрос как обеспечить, чтобы эти предикаты не пересекались. Ведь если два предиката вернут true на одно и то же значение, то действительно будет неоднозначность.

Понятно, что тут еще есть над чем подумать, но в общем идея очень даже рабочая. Я в ней недостатков пока не вижу. И она отлично сочетается с исходной архитектурой которую я озвучивал.

Такие перегрузки наверно имеет смысл описывать явно, по аналогии с расширяемыми правилами. Ведь по сути это тоже расширение, только не синтаксическое, а семантическое (на основе значений типов). Возможно синтаксис будет таким:
  macro ForEach : Ast.Expression
    syntax: "foreach" "(" pattern "in" collection ")" body
      where: pattern    = Ast.PatternWithGuard,
             collection = Ast.Expression,
             body       = Ast.Expression;
    require: collection.Type as X && !X.IsPrimitive
    require: X has <[ method GetEnumerator() : E ]>
  {
    <[ /* реализация по умолчанию реализующая паттерн "перечислитель" */ ]>
  }

  // Перегрузка макры ForEach. 
  macro ForEachIEnumarableT overload ForEach
    require: collection.Type is IEnumarable[_]
    priority: < ForEach // Срабатывает только если не срабатывает основной вариант
  {
    <[ /* реализация для IEnumarable[T] */ ]>
  }
  ...
  // Где-то в другом месте... возможно в другой сборке...
  // Так как тип array[_] более конкретный нежели IEnumarable[_], то для массивов 
  // срабатывает именно эта перегрузка!
  macro ForEachArray overload ForEach
    require: collection.Type is array[_]
    priority: < ForEach
  {
    <[ /* реализация для массива */ ]>
  }

То есть повторно грамматику не задаем, но явно описываем, что новый макрос (ForEachArray) перегружает старый (ForEach).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 18:27
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Нет трансформации АСТ -> Нет потери информации -> Нет проблем с автокомплитом.


Не, не так. Правильная цепочка в твоем случае блудет такая:
>Нет трансформации АСТ -> Нет потери информации -> нет автодополнения (делаем его вручную для каждого языка и макроса)

Ну, а про "Нет трансформации АСТ" ты мне расскажешь когда будешь описывать то как ты реализуешь макру linq.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 18:46
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


VD>>А, ну, вот у нас уже прогресс. Когда ты принимаешь мои предложения они у тебя сразу же становятся "твоими, вид в профиль".

WH>Ну, то есть сдираем то что я написал.
WH>Меняем синтаксис и объявляем своим.

Ну, это у тебя такой стиль. Я у тебя ничего не сдирал. В моем решении типизация идет только после разложения до примитивов (раскрытия макросов), как в Н1. Отличие от Н1 только в том, что есть SST, а в Н1 все запихивается в универсальное AST.

WH>Причем передрал криво.

WH>Про второе сообщение об ошибке "забыл" и сэкономил одну строчку.

Не не забыл. Оно просто не нужно. Сообщение которое породит match будет достаточно. Это и я и называю — "не делать лишней работы".

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

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

WH>Масса.
WH>Начиная с того что не ясно где и как хранить неоднозначный АСТ.

А его не будет. SST будет один. А раскрываться он будет одним макросом (для которого будет истинно условие).

WH>Но все что ты осилил это:

WH>

WH>Я уже говорил тебе, что не буду ничего обсуждать до предъявления тобой прсевдокода реализаций foreach, linq и PegGrammar с объяснением того что дает такая реализация.


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

Ты же просьбы показать хоть что-то упорно игнорируешь.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 01.06.11 20:36
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Не не забыл. Оно просто не нужно. Сообщение которое породит match будет достаточно. Это и я и называю — "не делать лишней работы".

              Message.HintOnce ("this means two branches of ``if'' or "
                                "``match'' have different types"));

(С)Typer.n
В ЯДРО КОМПИЛЯТОРА ЗАХАРДКОЖЕНА ИНФОРМАЦИЯ О МАКРОСЕ!!!!!!!!!!!!!!!!!

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

Лол.
Декларативный код тоже код.
И мой код не менее декларативный, чем твой.
На него просто сахар не насыпан.

VD>Ты же просьбы показать хоть что-то упорно игнорируешь.

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

VD>Понятно, что тут еще есть над чем подумать, но в общем идея очень даже рабочая. Я в ней недостатков пока не вижу. И она отлично сочетается с исходной архитектурой которую я озвучивал.


VD>Такие перегрузки наверно имеет смысл описывать явно, по аналогии с расширяемыми правилами. Ведь по сути это тоже расширение, только не синтаксическое, а семантическое (на основе значений типов). Возможно синтаксис будет таким:


Еще скажи что ты это все сам придумал.
Автор: WolfHound
Дата: 31.05.11
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[12]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 21:53
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Ничего я не игнорирую.

WH>Просто я думаю.

Ну, думай. Как на думаешь позови. Пока можешь почитать мой вариант
Автор: VladD2
Дата: 02.06.11
.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 01.06.11 22:06
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ну, думай. Как на думаешь позови. Пока можешь почитать мой вариант
Автор: VladD2
Дата: 02.06.11
.

Я знал все что ты напишешь еще до того как ты это написал.
Все что ты задумал это косметический ремонт Н1 который по сути ничего не решит.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[14]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.11 22:41
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Я знал все что ты напишешь еще до того как ты это написал.

WH>Все что ты задумал это косметический ремонт Н1 который по сути ничего не решит.

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

У меня задача создать решение которое не будет иметь ограничений и неудобств Н1.

Твои идеи я с интересом арссмотрел и нашел в них ряд фатальных недостатков. Если ты продумаешь их как следует, то увидишь их. Меня ты явно слушать не хочешь, так что ищи грабли сам.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 01.06.11 22:44
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>А VladD2 и WolfHound решают как же эту радость сделать "правильно". Пока весь спор сосредоточен вокруг того можно ли типизировать макросы без их раскрытия (предлагает WolfHound), или же есть такие макросы, которые только после типизирования и можно раскрыть (в этом уверен VladD2).

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

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

WH>Он верит в то что есть макросы, которые можно типизировать только после раскрытия.


А я верю в то, что есть макросы которые должны менять дерево типов, но для работы им нужна информация о типах выражений которые им передали. Пока у тебя все стройно выходит, кроме этого случая.
Re[5]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 02.06.11 09:35
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>А я верю в то, что есть макросы которые должны менять дерево типов, но для работы им нужна информация о типах выражений которые им передали. Пока у тебя все стройно выходит, кроме этого случая.

И в чем ты видишь проблему.
Ибо я проблем не вижу.

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

Я тут подумал и пришёл к выводу, что информацию о типизации нужно привязывать к самому АСТ.
abstract ast Expression
{
    Type : out ExpressionType;
}

abstract ast Literal
{
    Type : out ExpressionType;
}

abstract ast Pattern
{
    InType : in ExpressionType;
    Type : out PatternType;
}

in означает что значение этого поля приходит извне узла.
out означает что значение этого поля вычисляется внутри узла.

ExpressionType это всем привычные типы.
PatternType это тип паттерна. Фактически представляет собой Dictionary[Name, ExpressionType].

Как описывать структуру типов я еще думаю.

Вот таким образом литералы засовываются в выражения:
ast LiteralExpression : Expression
{
    syntax literal;
    literal : Literal;
}
typing
{
    Type = literal.Type;
}

Данная запись сахар к такой:
ast LiteralExpression : Expression
{
    syntax literal;
    literal : Literal;
}

tast TypedLiteralExpression for LiteralExpression
{
    Type = literal.Type;
}


Использование засахаренной записи не отменяет возможность реализации нескольких tast для одного ast.

А вот такм в паттерны:
ast LiteralPattern : Pattern
{
    syntax literal;
    literal : Literal;
}
typing
{
    ConvertibleTo(InType, literal.Type)
        @@@ $"Can't match $InType over $(literal.Type)."; // Если Location не указан то берется this.Location
    Type = PatternType(); // Пустой словарь ибо литерл не производит никакого связывания.
}


Добавим паттерны посложнее:
Задавать приоритеты парсинга мне лень. Не о них сейчас.
ast RoundsPattern : Pattern
{
    syntax "(" pattern ")";
    pattern : Pattern;
}
typing
{
    InType = pattern.InType;//Просто передаем входной тип во вложенный паттерн.
    Type = pattern.Type;//Возвращаем тип вложенного паттерна.
}

ast OrPattern : Pattern
{
    syntax lPattern "|" rPattern;
    lPattern : Pattern;
    rPattern : Pattern;
}
typing
{
    lPattern.InType = InType;
    rPattern.InType = InType;

    lPattern.Type = rPattern.Type
        @@@ $"Patterns must return same set of values.";
    Type = lPattern.Type;
}

//Позволяет одно и тоже выражение разобрать разными паттернами
ast AndPattern : Pattern
{
    syntax lPattern "&" rPattern;
    lPattern : Pattern;
    rPattern : Pattern;
}
typing
{
    lPattern.InType = InType;
    rPattern.InType = InType;

    AddPatterns([lPattern.Type, rPattern.Type], Type)
        @@@ "Names in patterns must not intersect.";
}

ast VarPattern : Pattern
{
    syntax name;
    name : Identifier;
}
typing
{
    Type = PatternType(name, InType);
}

ast AsPattern : Pattern
{
    syntax pattern "as" name;
    name : Identifier;
    pattern : Pattern;
}
typing
{
    pattern.InType = InType;
    exprType = PatternType(name, InType);
    AddPatterns([pattern.Type, exprType], Type)
        @@@ "Names in patterns must not intersect.";
}


Типизацию маняющую состав области видимости покажу в другой раз.
Я ее еще не додумал.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.06.11 15:16
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>А VladD2 и WolfHound решают как же эту радость сделать "правильно". Пока весь спор сосредоточен вокруг того можно ли типизировать макросы без их раскрытия (предлагает WolfHound), или же есть такие макросы, которые только после типизирования и можно раскрыть (в этом уверен VladD2).


Все с точностью до наоборот. Есть макросы которые можно типизировать до раскрытия. Есть те что нельзя. Есть макросы которые вообще должны читать типизированный код и переписывать его как им надо (но типизироваться он должен обычным образом). Ряд макросов требуют типизации отдельных параметров (foreach, например) чтобы по ним породить разный код. При этом только порожденный код может быть окончательно типизирован.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.06.11 15:21
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>А я верю в то, что есть макросы которые должны менять дерево типов, но для работы им нужна информация о типах выражений которые им передали. Пока у тебя все стройно выходит, кроме этого случая.


Пока у него просто ничего не выходит. Точнее выходят горы кода на ровном месте, дублирование типизации до и после раскрытия и прочая фигня.

Если бы чего-то выходило, то были бы примеры.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.06.11 15:29
Оценка:
Здравствуйте, WolfHound, Вы писали:

C>>А почему все так сложно по сравнению с Н1?

WH>1)Не так уж и сложно.

Сложно, сложно. Это всем кроме тебя очевидно.

WH>2)Можно насыпать сахару.


Сыпь. Только это делу не поможет.

WH>3)На макрах побольше Н1 сольет даже без сахара.


Пока что все с точностью до наоборот. Примеры в студию, будем обсуждать.

C>>Не то что бы я критично настроен, но зачем вообще отдельная типизация для всех конструкций, кроме встроенных в язык?

WH>Например PegGrammar без этого просто невозможно реализовать.
WH>Сейчас это делается руками в макросе жутким кодом.

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

WH>Макросам типа foreach необходима информация о типах для того чтобы сгенерировать код.


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

WH>И в целом это просто решит все проблемы с автокомплитом (включаяя сложные ДСЛ), навигацией, хинтами и сделает реализацию рефакторингов тривиальной.


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

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

Ты выкатил на гора уже добрый десяток рассказов в которых все замечательно и чудесно. Но как только ты начинаешь показывать код, так тотчас вера в эти рассказы улитучивается.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 03.06.11 16:10
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Можно ссылку на жудкий код? Чтобы все могли оценить масштабы выигрыша. Думаю всем будет дико интересно, что же они выиграют от нужды писать то что раньше писать было не надо.

http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/IntelliSenseSupport.n
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/Compiler/GrammarCompiler/GetScopeMethods.n
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/Compiler/GrammarCompiler/HandlerMethods.n
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/Grammar/GrammarTyper.Utils.n
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/Grammar/GrammarTyper.RemoveAllCaptures.n
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/Grammar/GrammarTyper.AddArgumentCaptures.n
И я не уверен что про все вспомнил.

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

Это не мешает их типизировать.

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

Автокомплита нет по тому что ИДЕ вон про ту гору кода (см выше) ничего не знает.
В моем подходе вся эти гора кода будет сгенерирована по ДСЛ. При этом никто не мешает сгенерировать еще много чего для того чтобы был автокомплит.
Я вообще фигею. Почему мне приходиться тебе говорить, что по ДСЛ можно сгенерировать что угодно?

VD>Пойми, слушать сказки о том как все будет хорошо никтому не интересно. Это любой может нафантазировать. Всем интересны детали. Только осмысливая их можно сказать является ли твой план фантазией которую невозможно реализовать, или все же он реалистичен.

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

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

Учитывая что ты даже не пытаешься слушать что тебе говорят...
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.06.11 17:09
Оценка:
Здравствуйте, WolfHound, Вы писали:

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

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

Примеры пойдут отдельными сообщениями в ответ на данное сообщение.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Пример 1: foreach
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.06.11 18:01
Оценка:
Пример 1: foreach

Рассматриваем упрощенную версию реализующую спецификацию C# (т.е. без немерловых наворотов). Вот его спецификация:

8.8.4 The foreach statement

The foreach statement enumerates the elements of a collection, executing an embedded statement for each element of the collection.
foreach-statement:

foreach ( local-variable-type identifier in expression ) embedded-statement

The type and identifier of a foreach statement declare the iteration variable of the statement. If the var keyword is given as the local-variable-type, the iteration variable is said to be an implicitly typed iteration variable, and its type is taken to be the element type of the foreach statement, as specified below. The iteration variable corresponds to a read-only local variable with a scope that extends over the embedded statement. During execution of a foreach statement, the iteration variable represents the collection element for which an iteration is currently being performed. A compile-time error occurs if the embedded statement attempts to modify the iteration variable (via assignment or the ++ and operators) or pass the iteration variable as a ref or out parameter.
The compile-time processing of a foreach statement first determines the collection type, enumerator type and element type of the expression. This determination proceeds as follows:
If the type X of expression is an array type then there is an implicit reference conversion from X to the System.Collections.IEnumerable interface (since System.Array implements this interface). The collection type is the System.Collections.IEnumerable interface, the enumerator type is the System.Collections.IEnumerator interface and the element type is the element type of the array type X.

Otherwise, determine whether the type X has an appropriate GetEnumerator method:
o Perform member lookup on the type X with identifier GetEnumerator and no type arguments. If the member lookup does not produce a match, or it produces an ambiguity, or produces a match that is not a method group, check for an enumerable interface as described below. It is recommended that a warning be issued if member lookup produces anything except a method group or no match.
o Perform overload resolution using the resulting method group and an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, check for an enumerable interface as described below. It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.
o If the return type E of the GetEnumerator method is not a class, struct or interface type, an error is produced and no further steps are taken.
o Member lookup is performed on E with the identifier Current and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a public instance property that permits reading, an error is produced and no further steps are taken.
o Member lookup is performed on E with the identifier MoveNext and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a method group, an error is produced and no further steps are taken.
o Overload resolution is performed on the method group with an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, or its return type is not bool, an error is produced and no further steps are taken.
o The collection type is X, the enumerator type is E, and the element type is the type of the Current property.

Otherwise, check for an enumerable interface:
o If there is exactly one type T such that there is an implicit conversion from X to the interface System.Collections.Generic.IEnumerable<T>, then the collection type is this interface, the enumerator type is the interface System.Collections.Generic.IEnumerator<T>, and the element type is T.
o Otherwise, if there is more than one such type T, then an error is produced and no further steps are taken.
o Otherwise, if there is an implicit conversion from X to the System.Collections.IEnumerable interface, then the collection type is this interface, the enumerator type is the interface System.Collections.IEnumerator, and the element type is object.
o Otherwise, an error is produced and no further steps are taken.
The above steps, if successful, unambiguously produce a collection type C, enumerator type E and element type T. A foreach statement of the form
foreach (V v in x) embedded-statement
is then expanded to:
{
    E e = ((C)(x)).GetEnumerator();
    try {
        V v;
        while (e.MoveNext()) {
            v = (V)(T)e.Current;
            embedded-statement
        }
    }
    finally {
        … // Dispose e
    }
}

The variable e is not visible to or accessible to the expression x or the embedded statement or any other source code of the program. The variable v is read-only in the embedded statement. If there is not an explicit conversion (§6.2) from T (the element type) to V (the type in the foreach statement), an error is produced and no further steps are taken. If x has the value null, a System.NullReferenceException is thrown at run-time.
An implementation is permitted to implement a given foreach-statement differently, e.g. for performance reasons, as long as the behavior is consistent with the above expansion.
The body of the finally block is constructed according to the following steps:
• If there is an implicit conversion from E to the System.IDisposable interface, then the finally clause is expanded to the semantic equivalent of:
finally {
    ((System.IDisposable)e).Dispose();
}

except that if e is a value type, or a type parameter instantiated to a value type, then the cast of e to System.IDisposable will not cause boxing to occur.
• Otherwise, if E is a sealed type, the finally clause is expanded to an empty block:
finally {
}

• Otherwise, the finally clause is expanded to:
finally {
    System.IDisposable d = e as System.IDisposable;
    if (d != null) d.Dispose();
}

The local variable d is not visible to or accessible to any user code. In particular, it does not conflict with any other variable whose scope includes the finally block.
The order in which foreach traverses the elements of an array, is as follows: For single-dimensional arrays elements are traversed in increasing index order, starting with index 0 and ending with index Length – 1. For multi-dimensional arrays, elements are traversed such that the indices of the rightmost dimension are increased first, then the next left dimension, and so on to the left.
The following example prints out each value in a two-dimensional array, in element order:
using System;
class Test
{
    static void Main() {
        double[,] values = {
            {1.2, 2.3, 3.4, 4.5},
            {5.6, 6.7, 7.8, 8.9}
        };
        foreach (double elementValue in values)
            Console.Write("{0} ", elementValue);
        Console.WriteLine();
    }
}

The output produced is as follows:
1.2 2.3 3.4 4.5 5.6 6.7 7.8 8.9
In the example
int[] numbers = { 1, 3, 5, 7, 9 };
foreach (var n in numbers) Console.WriteLine(n);
the type of n is inferred to be int, the element type of numbers.


Вот как будет выглядеть макрос вводящий foreach:
macro ForEac 
  syntax "foreach" "(" var "in" collection ")" body;
  where var        = VariableDeclarationExpression,
        collection = Expression,
        body       = Expression;
{
  ...
}

Иными словами у нас есть три выражения: var, collection и body.

Проблема реализации foreach заключается в том, что связь между collection и var не определена. А до определения этой связи var невозможно типизировать. Ну, а раз невозможно типизировать var, то невозможно типизировать и body.

Приведенная выше спецификация говорит нам, что связь между collection и var определяется путем анализа типа collection. Именно это требует прибегать к типизации collection в реализации foreach-а в Н1.

Стало быть типизация collection должна быть произведена до попытки типизации макроса в целом и тем более его параметров var и body.

Если collection = это массив, то цикл должен будет быть переписан в (упрощенно):
def collection = $collection;
for (mutable i = 0; i < collection.Length; i++)
{
  def $var = collection[i];
  $body
}

При этом связь между collection.Type и var.Type будет осуществляться через индексатор массива, а значит тип будет зависеть от типа элемента массива (там есть нюансы с многомерными массивами и с массивами приведенными к типу System.Array, но их можно пока опустить).

Если collection = это объект реализующий паттерн "энумератор", то связь получается очень не очевидной. Нам надо убедиться, что тип collection.Type реализует метод GetEnumerator и проверить, что GetEnumerator() возвращает тип который реализует MoveNext() и Current. При этом нужно совершить тучу проверок и в некоторых случаях выдать сообщение об ошибке.

В этом случае зависимость между collection.Type и var.Type будет:
def x = collection.Type.Lookup(<[ GetEnumerator() : _ ]>).TerurnType;
assert(x != null);
def moveNext = x.Lookup(<[ MoveNext() : bool ]>);
assert(moveNext != null);

def current = x.Lookup(<[ Current : _ ]>);
assert(current != null);

var.Type = current.Type;


При этом нам нужно породить вот такой вот код:
def e = $collection.GetEnumerator();
try
{
  $body
  while (e.MoveNext())
  {
    def $var = e.Current;
    $body
  }
}
finally
{
  ... // Dispose e
}


В третьем случае для определения типа переменной нужно узнать реализует ли collection.Type IEnumerable[T] и уже использовать это T как тип переменной.

def e = ($collection :> IEnumerable[_]).GetEnumerator();
try
{
  $body
  while (e.MoveNext())
  {
    def $var = e.Current;
    $body
  }
}
finally
{
  ... // Dispose e
}


Вычислив тип var.Type мы можем преступить к типизации body. Если мы просто раскроем макрос, то типизация body будет произведена автоматически.

Теперь вопросы:
1. Как будет выглядеть тот код макроса с типизацией "по верхам"?
2. Как будет выглядеть декларативное описание выявления типа для var.Type?
3. Как будет выглядеть типизация body при том условии, что в нем встречаются не связанные ссылки на var, а как мы видим var перед использованием в body нужно преобразовать в определение переменной (пока что это просто имя).
4. Зачем производить типизацию var и body вручную, когда можно просто сгенерировать нужный код и позволить стандартному типизатору его типизировать?

Далее, ответив на эти вопросы, можно усложнить задачу и вспомнить о том, что в Nemerle foreach поддерживает паттетр-матчинг (как в переменной, так и в теле макроса) и представить себе как усложнится типизация с учетом этого факта.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 03.06.11 18:02
Оценка:
Здравствуйте, VladD2, Вы писали:

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


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

Какое из этих слов тебе не ясно?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.06.11 18:28
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


VD>>Можно ссылку на жудкий код? Чтобы все могли оценить масштабы выигрыша. Думаю всем будет дико интересно, что же они выиграют от нужды писать то что раньше писать было не надо.

WH>http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/IntelliSenseSupport.n

Ага. Вижу! 10 строчек и мы получаем навигацию по году!

WH>http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/Compiler/GrammarCompiler/GetScopeMethods.n

WH>http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/Compiler/GrammarCompiler/HandlerMethods.n
WH>http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/Grammar/GrammarTyper.Utils.n
WH>http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/Grammar/GrammarTyper.RemoveAllCaptures.n
WH>http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/Grammar/GrammarTyper.AddArgumentCaptures.n

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

Заметь, данная обработка невозможна в отдельных правилах (АСТ-ветках). Она возможна только при наличии полной модели грамматики.

Как ты себе видишь эти проверки привязанными к отельным веткам?

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

WH>И я не уверен что про все вспомнил.


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

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

WH>Это не мешает их типизировать.

Вот можно с этого места по подробнее?

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

WH>Автокомплита нет по тому что ИДЕ вон про ту гору кода (см выше) ничего не знает.

Я тебе открою сикрет. Автокомплита нет, потому что IDE не знает про атрибуты. В них комплита нет в принципе.
Горы кода тоже нет. Ты весь его повторишь слово в слово.
И если IDE узнает про этот код, то ровным счетом ничего не изменится. IDE нужен список возможных вариантов. Он есть в модели. Но он никак не связан с проверками. Комплит должен пахать даже когда модель содержит горы ошибок.

А что будет с комплитом при типизации "."? Там уже списокм правил не отделаешся. Нужно будет осуществлять разрешение перегрузки в процессе которого формировать список допустимых элементов.

WH>В моем подходе вся эти гора кода будет сгенерирована по ДСЛ. При этом никто не мешает сгенерировать еще много чего для того чтобы был автокомплит.


Ну, покажи свой чудо-ДСЛ. С чего в нем станет существенно меньше кода?

WH>Я вообще фигею. Почему мне приходиться тебе говорить, что по ДСЛ можно сгенерировать что угодно?


Да потому что ДСЛ — это базворд. Красивое слово. А в реальности у тебя есть задача и алгоритм ее решения. ДСЛ может только сделать вид ее решения чуть красивее. Но если ты не описываешь алгоритма, то красиве слова про ДСЛ — это только громкие, но пустые слова.

Я устал выщарапывать из тебя информацию по крупицам. Может ты все же изложишь свою идею на примерах и с полноценным объяснением?

На уровен абстракции "ДСЛ" я тебе тоже могу скзать, что вот создай к приведенному коду ДСЛ и код станет проще и короче. И что?

WH>Я тебе уже несколько раз сказал, что я не закончил формализацию поиска имен.

WH>Без этого я не могу выдать больше деталей, чем уже выдал.

ОК. На это надо еще 3 года жизни?

Когда закончишь, подходи вот сюда
Автор: VladD2
Дата: 03.06.11
. И постарайся максимально полно описать решение приведенной там задачи. Потом разберем linq и т.п.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.06.11 18:29
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


Ждем. До тех пор, просьба, данный вопрос не поднимать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.06.11 18:30
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Нет. Отрефакторенный N1 будет называеться N1.5 (т.е. без полторашки не разобраться).


Кстати, как там рефакторинг SRE? На каком ты этапе?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 03.06.11 19:01
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ага. Вижу! 10 строчек и мы получаем навигацию по году!

10!?
Да там строк 60 чистого кода.
И это только на такой примитив как навигация.

VD>Ну, и что тут жуткого?

То что это вообще пришлось писать.

VD>Ты обрати внимание, что то что ты называешь типизацией — это проверка корректности модели DSL-я и сверка его со связанными методами-обработчиками.

Так это и есть типизация.

VD>Заметь, данная обработка невозможна в отдельных правилах (АСТ-ветках). Она возможна только при наличии полной модели грамматики.

И что?

VD>Как ты себе видишь эти проверки привязанными к отельным веткам?

Легко.
Особенно учитывая что в моей концепции ветки связаны друг с другом.
Вот посмотри на типизацию паттернов.

VD>В общем, опробуй изобрази тоже самое но в своей гипотетической системе. Может тогда будет понятно о чем ты ведешь речь.

Мне не хватает поиска имен.

VD>А я уверен, что как бы ты не делал тебе придется сделать все те же самые проверки. В лучшем случае кода получится примерно столько же. Ну, может ты сможешь сгладить углы и убрать некоторые неудобства. Но что кардинально может измениться?

Кода будет в разы меньше.
Он будет декларативным.
Появится автокомплит.

VD>Вот можно с этого места по подробнее?

Формализую поиск имен будет подробнее.

VD>Я тебе открою сикрет. Автокомплита нет, потому что IDE не знает про атрибуты. В них комплита нет в принципе.

Ну давай перенесем его внутрь строки внутри метода.
Автокомплит после этого появится?

VD>Горы кода тоже нет. Ты весь его повторишь слово в слово.

Я все это затеял чтобы его не писать.

VD>И если IDE узнает про этот код, то ровным счетом ничего не изменится. IDE нужен список возможных вариантов. Он есть в модели. Но он никак не связан с проверками. Комплит должен пахать даже когда модель содержит горы ошибок.

1)У меня есть модель.
2)По проверкам можно понять из какого места модели достаются имена.

VD>Ну, покажи свой чудо-ДСЛ. С чего в нем станет существенно меньше кода?

И уже показал.
Например я показал как типизировать паттрены.
Там полный код.
Паттернам которые распознают конструкторы итп нужен поиск имен.

VD>Я устал выщарапывать из тебя информацию по крупицам. Может ты все же изложишь свою идею на примерах и с полноценным объяснением?

Мне не хватает поиска имен.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 03.06.11 19:01
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ждем. До тех пор, просьба, данный вопрос не поднимать.

ТАК ТЫ ЖЕ ЕГО ПОДНИМАЕШЬ!
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.06.11 19:58
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>Я тебе открою сикрет. Автокомплита нет, потому что IDE не знает про атрибуты. В них комплита нет в принципе.

WH>Ну давай перенесем его внутрь строки внутри метода.
WH>Автокомплит после этого появится?

Да. И я привел тебе практически реальный код что нужно написать.

VD>>Горы кода тоже нет. Ты весь его повторишь слово в слово.

WH>Я все это затеял чтобы его не писать.

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

VD>>И если IDE узнает про этот код, то ровным счетом ничего не изменится. IDE нужен список возможных вариантов. Он есть в модели. Но он никак не связан с проверками. Комплит должен пахать даже когда модель содержит горы ошибок.

WH>1)У меня есть модель.
WH>2)По проверкам можно понять из какого места модели достаются имена.

Только имена в комплите частичные. Да с типизацией это как с таковой не связано. Это скорее с разрешением имен связано. Но опять таки прямой связи не будет. И придется что-то подсказывать IDE. В лучшем случае это удастся запихать в библиотеки или ДСЛ.

WH>И уже показал.

WH>Например я показал как типизировать паттрены.
WH>Там полный код.

Ой, надо прикопать это письмо. Я тебе потом покажу реальный код этого дела и тебе станет стыдно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 03.06.11 20:18
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>>>Я тебе открою сикрет. Автокомплита нет, потому что IDE не знает про атрибуты. В них комплита нет в принципе.

WH>>Ну давай перенесем его внутрь строки внутри метода.
WH>>Автокомплит после этого появится?
VD>Да. И я привел тебе практически реальный код что нужно написать.
Где?

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

У меня останутся только декларации типов.

VD>Только имена в комплите частичные.

И что?

VD>Да с типизацией это как с таковой не связано. Это скорее с разрешением имен связано.

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

VD>Но опять таки прямой связи не будет. И придется что-то подсказывать IDE. В лучшем случае это удастся запихать в библиотеки или ДСЛ.

Ну да.
Подсказкой для ИДЕ будет описание того как имя искать.
Собственно все, что нужно это два режима поиска имени.
Оди по точному совпадению для типизации и показа ошибок, а второй для IDE.
Тк у на ДСЛ и мы сами генерирем код сделать их не составит никакой проблемы.
Причем в ДСЛ об это не будет ни слова.
Те глядя на код типа:
    resolve(name, далее объяснения как его искать и куда девать найденную информацию)

ИДЕ все поймет.
Оно возьмет недопарсеное имя. И начнет его искать согласно объяснениям. Но искать будет не точное совпадение, а начало при этом игнорируя регистр символов.

VD>Ой, надо прикопать это письмо. Я тебе потом покажу реальный код этого дела и тебе станет стыдно.

Не станет.
Ибо реальный код примерно таким и будет. Я, конечно, говорю про реализацию моей идеи.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[12]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.06.11 21:53
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>Да. И я привел тебе практически реальный код что нужно написать.

WH>Где?

В предыдущем сообщении.

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

WH>У меня останутся только декларации типов.

Какие еще декларации? Там надо сравнивать количество аргументов и выдавать сообщение, если оно не то. И так далее. Там просто куча проверок и выдача сообщений если они не прошли.

VD>>Только имена в комплите частичные.

WH>И что?

То что без приседаний не обойтись. Сейчас оные вынесены в тайпер. У тебя они будут торчать наружу.

VD>>Да с типизацией это как с таковой не связано. Это скорее с разрешением имен связано.

WH>Эти процессы настолько связаны, что я их не разделяю.

А, кстати, зря. Связывание имен куда более шустрая вещь. Для рефакторинга переименования нужно только связывание. Возможно выделение связывания в отдельную фазу было бы полезно.

WH>Одно без другого просто не имеет смысла.


Как видишь, имеет.

VD>>Но опять таки прямой связи не будет. И придется что-то подсказывать IDE. В лучшем случае это удастся запихать в библиотеки или ДСЛ.

WH>Ну да.
WH>Подсказкой для ИДЕ будет описание того как имя искать.
WH>Собственно все, что нужно это два режима поиска имени.
WH>Оди по точному совпадению для типизации и показа ошибок, а второй для IDE.
WH>Тк у на ДСЛ и мы сами генерирем код сделать их не составит никакой проблемы.
WH>Причем в ДСЛ об это не будет ни слова.
WH>Те глядя на код типа:
WH>
WH>    resolve(name, далее объяснения как его искать и куда девать найденную информацию)
WH>

WH>ИДЕ все поймет.

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

WH>Оно возьмет недопарсеное имя. И начнет его искать согласно объяснениям. Но искать будет не точное совпадение, а начало при этом игнорируя регистр символов.


В Решарпере еще поддерживатеся поиск по заглавным буквам или с паттерном.
Плюс проблема в том, что имя ищется не только в областях видимости. Еще же есть поиск членов. При этом изменяется способ работы типизатора. Вместо поиска лучшего варианта начинается перебор всех вариантов и объединение их в общий список (с устранением дублирования). Например, при поиске xs.Select(x => x.Su|) просходит перебор всех вариантов перегрзки Select умноженный на все варианты перегрузки "Su*". То есть обрабатываются результаты тех ветвей типизации которые отбрасываются при нормальном ходе типизации.
Я в таких случаях переписывал код так чтобы он был максимально корректным и мог продолжать типизацию не смотря ни на что. Например в приведенном примере я создавал объект отложенной типизации и заменял им x.Su. Далее в этом объекте уже собиралась нужная информация.
Так что без приседаний тут не обойтись. И их надо максимально заложить в ядро. Чтобы не приходилось приседать пользователям. А то я тоже мог бы оттипизировать "?." вручную. но это же бешеная работа. Куда проще переписать код.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 03.06.11 22:15
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>В предыдущем сообщении.

В каком?

VD>Какие еще декларации? Там надо сравнивать количество аргументов и выдавать сообщение, если оно не то. И так далее. Там просто куча проверок и выдача сообщений если они не прошли.

Использую код разрешения перегрузки.
Он же и сообщения об ошибках покажет.

VD>То что без приседаний не обойтись. Сейчас оные вынесены в тайпер. У тебя они будут торчать наружу.

Никуда они у меня торчать не будут.
Они будут жить исключительно внутри сгенерированного кода.

VD>А, кстати, зря. Связывание имен куда более шустрая вещь. Для рефакторинга переименования нужно только связывание. Возможно выделение связывания в отдельную фазу было бы полезно.

Правда? А разрешение перегрузки для рефакторинга уже не нужно?

VD>Как видишь, имеет.

Не вижу.

VD>Это объяснение придется давать очень уж детально.

Не придется. Я сейчас как раз формирую концепцию того как именно это объяснять чтобы не пришлось много писать.

VD>У разных языков разные принципы поиска имен. Есть даже динамические.

А вот тут ты ошибаешься.
Имена ищут очень похожими способами.
Так что это довольно легко обобщить.

VD>В Решарпере еще поддерживатеся поиск по заглавным буквам или с паттерном.

Так тоже можно.
Короче два варианта:
Точное совпадение. Для компиляции и сообщений об ошибках.
Не точное совпадение для интелисенса.

Причем оба варианта будут сгенерированы компилятором.

VD>Плюс проблема в том, что имя ищется не только в областях видимости. Еще же есть поиск членов.

Я в курсе.

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

А я о чем?
Я декларативно описываю связи.
А всей это байдой с отложенной типизацией будет занят компилятор ДСЛя. Он железный не развалиться.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[14]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.06.11 23:11
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>Какие еще декларации? Там надо сравнивать количество аргументов и выдавать сообщение, если оно не то. И так далее. Там просто куча проверок и выдача сообщений если они не прошли.

WH>Использую код разрешения перегрузки.
WH>Он же и сообщения об ошибках покажет.

Гы-гы. Только что ты мне тыкал общими сообщениями об ошибках в Н1, а сейчас тоже самое предлагаешь.
Разрешение перегрузки тебе скажет, что нет нужного метода и все. А тут конкретная задача. Надо взять метод, сформировать по правилу список ожидаемых типов и сравнить их с методом выдав конкретные советы по устранению проблем.

Так что если ты хочешь качественной диагностики, то напишешь такой же код.

VD>>То что без приседаний не обойтись. Сейчас оные вынесены в тайпер. У тебя они будут торчать наружу.

WH>Никуда они у меня торчать не будут.
WH>Они будут жить исключительно внутри сгенерированного кода.

Чего? Ты же по верхнему типизировать собрался?

WH>Правда? А разрешение перегрузки для рефакторинга уже не нужно?

Нет. Оно не изменится. Ты же только имя меняешь. Разве что ли для выявления случайных перекрытий.
Но тут очень важно найти методы содержащие нужные имена. Далее уже можно их стипизровать. Это будет куда шустрее полной типизации всего проекта. В рефакторингах много химии делается для ускорения их работы.

VD>>Это объяснение придется давать очень уж детально.

WH>Не придется. Я сейчас как раз формирую концепцию того как именно это объяснять чтобы не пришлось много писать.

Давай.

VD>>У разных языков разные принципы поиска имен. Есть даже динамические.

WH>А вот тут ты ошибаешься.
WH>Имена ищут очень похожими способами.
WH>Так что это довольно легко обобщить.

Как на счет динамических переменные в Лисе?

VD>>В Решарпере еще поддерживатеся поиск по заглавным буквам или с паттерном.

WH>Так тоже можно.
WH>Короче два варианта:
WH>Точное совпадение. Для компиляции и сообщений об ошибках.
WH>Не точное совпадение для интелисенса.

Ладно. Это бесполезно объяснять. Это надо прочувствовать на своей шкуре.

WH>А всей это байдой с отложенной типизацией будет занят компилятор ДСЛя. Он железный не развалиться.


Если только. Но ты не представляешь себе реальной сложности этого дела.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 04.06.11 12:03
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Гы-гы. Только что ты мне тыкал общими сообщениями об ошибках в Н1, а сейчас тоже самое предлагаешь.

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

WH>>Никуда они у меня торчать не будут.

WH>>Они будут жить исключительно внутри сгенерированного кода.
VD>Чего? Ты же по верхнему типизировать собрался?
Ну да. Они будут жить внутри кода, который будет сгенерирован компилятором ДСЛ.
А что там нагенерирует компилятор всем до лампочки.

VD>Нет. Оно не изменится. Ты же только имя меняешь. Разве что ли для выявления случайных перекрытий.

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

VD>Как на счет динамических переменные в Лисе?

Ты еще спроси, как я eval типизировать буду.
В динамически типизируемых языках много всяких пакостей.
Если же делать аналог в статике то использование фунцией динамических переменных должно отражаться в ее сигнатуре, а дальше все просто.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 05.06.11 18:24
Оценка:
Здравствуйте, WolfHound, Вы писали:

Чем больше я думаю, на эту тему тем больше убеждаюсь в том, что ядро системы должно быть реактивным.
1)У нас будет очень простой и предельно декларативный язык описания типизации.
2)Не смотря на это код, сгенерированный по этому языку будет императивный до мозга костей, что положительно скажется на производительности.
3)Реактивное программирование это, по сути, формализм для инкрементального обновления модели. Т.к. не будет полного пересчета всего то это даст заметное ускорение.
4)Обсчет реактивной модели можно автоматически распараллелить.
5)Реактивность позволит из тел методов создавать и модифицировать типы.

Руками все это сделать не возможно. Как следствие от языка описания типизации никуда не уйти.
Другого способа сделать быстрое, надежное и простое в использовании решение я не вижу.
Ручной императив а-ля Н1 не вариант ваще.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Размышления о типизаторе для Н2
От: Аноним  
Дата: 06.06.11 12:35
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


WH>Чем больше я думаю, на эту тему тем больше убеждаюсь в том, что ядро системы должно быть реактивным.

WH>1)У нас будет очень простой и предельно декларативный язык описания типизации.
WH>2)Не смотря на это код, сгенерированный по этому языку будет императивный до мозга костей, что положительно скажется на производительности.
WH>3)Реактивное программирование это, по сути, формализм для инкрементального обновления модели. Т.к. не будет полного пересчета всего то это даст заметное ускорение.
WH>4)Обсчет реактивной модели можно автоматически распараллелить.
WH>5)Реактивность позволит из тел методов создавать и модифицировать типы.

WH>Руками все это сделать не возможно. Как следствие от языка описания типизации никуда не уйти.

WH>Другого способа сделать быстрое, надежное и простое в использовании решение я не вижу.
WH>Ручной императив а-ля Н1 не вариант ваще.

Реактивное программирование тут сомнительно, так как изменения могут касаться самого существования узлов с перестройкой графа в целом.
Re[3]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 06.06.11 12:52
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Реактивное программирование тут сомнительно, так как изменения могут касаться самого существования узлов с перестройкой графа в целом.

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

WH>Здравствуйте, <Аноним>, Вы писали:


А>>Реактивное программирование тут сомнительно, так как изменения могут касаться самого существования узлов с перестройкой графа в целом.

WH>И в чем проблема?

В том что аналогия с excel не верна, так как там граф всзоимодействий меняется локально
Re[16]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.06.11 15:15
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>Гы-гы. Только что ты мне тыкал общими сообщениями об ошибках в Н1, а сейчас тоже самое предлагаешь.

WH>Вовсе нет.
WH>Сообщения, выдаваемые при разрешении перегрузки вполне подходят в данном случае.

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

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

VD>>Нет. Оно не изменится. Ты же только имя меняешь. Разве что ли для выявления случайных перекрытий.

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

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

WH>И их можно использовать не только для инкрементального обновления дерева проекта, но и для навигации и прочих рефакторингов.


Это все на словах. Реально там нужно очень многое продумывать. В любом случае разрешать в макросах уровня выражения генерировать типы которые будут видны в других методах слишком опасны. Это голимый императив. От него добра ждать не приходится.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 06.06.11 17:04
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>В том что аналогия с excel не верна, так как там граф всзоимодействий меняется локально

И в чем проблема?
Удаление и изменение узла графа мало чем отличаются.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[17]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 06.06.11 17:13
Оценка:
Здравствуйте, VladD2, Вы писали:

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

Я то почитал. А ты?

VD>Я пока что не вижу как тут преплетается реактивность. А вот то, что она поставит крест на потокобезопасностия уже предвидеть могу. Нам нужно чтобы методы могли типизироваться параллельно.

Не поставит.
Реактивную систему можно параллелить.
Руками это делать, конечно, застрелишься, но я и не предлагаю делать это руками.
ДСЛ наше все.

VD>Это все на словах. Реально там нужно очень многое продумывать. В любом случае разрешать в макросах уровня выражения генерировать типы которые будут видны в других методах слишком опасны. Это голимый императив. От него добра ждать не приходится.

То, что не видишь хорошего решения не значит что его нет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[18]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.06.11 17:39
Оценка:
Здравствуйте, WolfHound, Вы писали:

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

WH>Я то почитал.

Хреново значит читал.

WH>А ты?


Я их писал.

VD>>Я пока что не вижу как тут преплетается реактивность. А вот то, что она поставит крест на потокобезопасностия уже предвидеть могу. Нам нужно чтобы методы могли типизироваться параллельно.

WH>Не поставит.
WH>Реактивную систему можно параллелить.
WH>Руками это делать, конечно, застрелишься, но я и не предлагаю делать это руками.
WH>ДСЛ наше все.

Все что имеет общие связки параллелиться будет плохо. Хорошо параллелятся только вычисления не связанные общими данными.

VD>>Это все на словах. Реально там нужно очень многое продумывать. В любом случае разрешать в макросах уровня выражения генерировать типы которые будут видны в других методах слишком опасны. Это голимый императив. От него добра ждать не приходится.

WH>То, что не видишь хорошего решения не значит что его нет.

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

Короче, идею впихнуть сюда реактивность я на ус намотал. Но ее надо серьезно продумывать и проверять. Пока что я не могу сказать что она точно взлетит.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[19]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 06.06.11 18:06
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Все что имеет общие связки параллелиться будет плохо. Хорошо параллелятся только вычисления не связанные общими данными.

Нас посетил КО.

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

Реактивность успешно применяют во множестве решений.

VD>Короче, идею впихнуть сюда реактивность я на ус намотал. Но ее надо серьезно продумывать и проверять. Пока что я не могу сказать что она точно взлетит.

Модель вычислений взлету не мешает.
С реализацией придется повозиться.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 07.06.11 08:14
Оценка:
Здравствуйте, WolfHound, Вы писали:

pred ConvertibleTo(from : Type, itemType : Type)
mode (in, in) is semidet //Проверяет что один тип приводим к другому.
mode (in, out) is multi  //При помощи бектрекинга перебирает все типы к которым можно привести данный.
//Реализацию выдумавать лень.


//Предикат, который достает тип элемента коллекции.
//Предикат объявлен абстрактным, чтобы его можно было расширять
//Это позволит реализовать этот предикат для коллекций, у которых нет IEnumirable
abstract pred CollectionItemType(collectionType : Type :: in, itemType : Type :: out) is nondet;

//Конкретный предикат.
pred GenericIEnumirableItemType(collectionType, itemType) extends CollectionItemType
{
    ConvertibleTo(collectionType, type);//Перебираем типы
    IEnumerable[itemType] = type;//Проверяем есть ли среди них IEnumerable[_] и связываем itemType
}
//Как вариант можно написать так:
//ConvertibleTo(collectionType, IEnumerable[itemType]);


pred IEnumirableItemType(collectionType, itemType) extends CollectionItemType
{//Тут все тоже самое
    ConvertibleTo(collectionType, type);
    IEnumerable = type;
    itemType = object;//Только возвращаем всегда object.
}

//Задаем порядок.
//Если GenericIEnumirableItemType нашол ответ то IEnumirableItemType проверяться не будет
order IEnumirableItemType < GenericIEnumirableItemType;

//При желании можно воткнуть что-то между ними
order IEnumirableItemType < MyCollectionItemType < GenericIEnumirableItemType;

Теперь при помощи расширяемого предиката CollectionItemType можно получить тип коллекции.
Далее типизируем паттерн
Автор: WolfHound
Дата: 02.06.11
.
ast ForEach : Expression
{
    syntax "foreach" "(" pattern "in" collection ")" body;
    pattern    : Pattern;
    collection : Expression;
    body       : Expression;
}
typing
{
    CollectionItemType(collection.Type, pattern.InType);
    newscope body add VarsFromPatternType(pattern.Type);
    ConvertibleTo(body.Type, #void);
    Type = #void;
}

newscope создает пространство имен, вложенное в текущее и типизирует с его помощью указанные выражения. В данном случае body.
VarsFromPatternType превращает тип паттерна в список переменных.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.06.11 15:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Реактивное программирование тут сомнительно, так как изменения могут касаться самого существования узлов с перестройкой графа в целом.


Это как раз решаемая задача. Например, в knockout (реактивная библиотека для построения Web UI) реактивная модель позволяет динамически менять DOM HTML-я. А DOM HTML-я — это тоже себе дерево. Раз можно менять его, то можно менять и деревья описывающие данные о программе.

Вопрос только как это скажется на производительности и возможности расспрашивания вычислений. Боюсь, что все может стать настолько сложным и/или медленным, что идея реактивности не взлетит.

Единственная надежда на DSL-изацию вывода типов. Тут я согласен с WolfHound-ом. DSL-изацию может позволить удержать сложность в разумных рамках при этом не скупясь на хамские (для гражданского кода) оптимизации.

В общем, идею реактивности надо как следует рассмотреть (а значит не сбрасывать со счетов). Если она прокатит, то это может быть решением очень многих проблем. От допущения псевдо-императивного изменения дерева типов из макросов уровня выражения, до обеспечения инкрементального обновления проекта. А это может существенно поднять производительность в режиме IDE.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.06.11 18:19
Оценка:
Здравствуйте, WolfHound, Вы писали:

О! Хоть что-то конкретное. Поглядел, но как-то не увидел многих деталей.

В моем варианте
Автор: VladD2
Дата: 06.06.11
приведено решение соответствующее спецификации C#. Плюс у меня приведен код переписывания. Другими словами из моего варианта можно понять как все будет работать в целом.

Из твоего же кода ясны только отдельные детали. Общей картины нет. И невозможно оценить общий объем кода.
Так что жду полноценного описания соответствующего моему примеру (или Н1).

Ниже вопросы и критика того что есть.

WH>pred ConvertibleTo(from : Type, itemType : Type)


Прежде чем применять какой-то новый язык надо объяснить его семантику и синтаксис. Иначе тебя никто не поймет.
Отсылать к изучении Меркури не стоит. Никто не будет его учить чтобы писать макросы.

WH>mode (in, in) is semidet //Проверяет что один тип приводим к другому.

WH>mode (in, out) is multi //При помощи бектрекинга перебирает все типы к которым можно привести данный.

Что это за хрень? Она не используется нигде ниже. Зачем ее вообще было приводить?

Потом что это за птичий язык? Что за невнятные сокращения — "semidet", "multi", "mode"? Я так понимаю этот стиль почерпнут из Меркури? Не надо сдирать у него плохоие черты. Имена должны быть внятными и поясняться перед использованием.

WH>При помощи бектрекинга перебирает все типы к которым можно привести данный.


Зачем? Почему нельзя просто возвратить список? В общем, ничего не понятно.

WH>//Реализацию выдумавать лень.

Она и не нужна, если это встроенные функции. Но нужно объяснить семантику. Иначе это очередная реинкарнация притчи об утюге. Знаешь такую?

WH>//Предикат, который достает тип элемента коллекции.

WH>//Предикат объявлен абстрактным, чтобы его можно было расширять
WH>//Это позволит реализовать этот предикат для коллекций, у которых нет IEnumirable
WH>abstract pred CollectionItemType(collectionType : Type :: in, itemType : Type :: out) is nondet;

Вот и покажи как будет выглядеть реализация этого предиката для коллекции не реализующей IEnumirable. Причем, чем детальнее, тем лучше. При этом загляни в спецификацию C# и повтори ее на своем языке. Интересны:
1. Как осуществляется анализ членов типа коллекции.
2. Как из членов добывается информация о типах возвращаемого значения и параметров. Для типов не реализующих IEnumirable нужно:
2.1. Убедиться, что у тип коллекции не является встроенным типом или делегатом (является структурой или классом).
2.2. Коллекция реализует метод GetEnumerator с сигнатурой "GetEnumerator() : e".
2.2. Тип возвращаемого значения GetEnumerator, т.е. тип "e" должен реализовывать метод MoveNext с сигнатурой "MoveNext() : bool" и свойство Current с сигнатурой "Current : elemType { get; }". Если метод или свойство не определено или у них неподходящие сигнатуры, об этом надо выдать сообщение (сообщение об ошибке).
2.3. Типом коллекции должен стать тип elemType, т.е. тип свойства Current у объекта который возвращается методом GetEnumerator. Обращаю особое внимание, что типизация других вариантов при этом не должна проводиться. То есть, если найден GetEnumerator, то далее типизатор должен добиваться от программиста наличия корректно оформленного паттерна "перечеслитель" и игнорировать другие варианты даже если тип реализует интерфейс IEnumerable.

Что такое ":: out" тоже не ясно. Это тоже надо пояснять.

WH>//Конкретный предикат.

WH>pred GenericIEnumirableItemType(collectionType, itemType) extends CollectionItemType
WH>{
WH> ConvertibleTo(collectionType, type);//Перебираем типы
WH> IEnumerable[itemType] = type;//Проверяем есть ли среди них IEnumerable[_] и связываем itemType
WH>}
WH>//Как вариант можно написать так:
WH>//ConvertibleTo(collectionType, IEnumerable[itemType]);

А где должны располагаться эти "pred"?

WH>pred IEnumirableItemType(collectionType, itemType) extends CollectionItemType

WH>{//Тут все тоже самое
WH> ConvertibleTo(collectionType, type);
WH> IEnumerable = type;

Что такое "type"? Это переменная типа? Откуда она взялась? Какова ее область видимости? Мы вводим переменные без объявления? Это противоречит духу немерла. Плюс как отличать введение переменной и использование ранее определенных? Хочется нахватать граблей Руби?

Почему object?

WH> itemType = object;//Только возвращаем всегда object.

WH>}

В C# для foreach по IEnumerable используется явное приведение типов. В немерле для тех же целей используется ПМ. Где и как это учитывается?

WH>//Задаем порядок.

WH>//Если GenericIEnumirableItemType нашол ответ то IEnumirableItemType проверяться не будет
WH>order IEnumirableItemType < GenericIEnumirableItemType;

WH>//При желании можно воткнуть что-то между ними

WH>order IEnumirableItemType < MyCollectionItemType < GenericIEnumirableItemType;

Опять внешние объявления? Где они будут располагаться? Как увидеть связь с макросами?

WH>Теперь при помощи расширяемого предиката CollectionItemType можно получить тип коллекции.

WH>Далее типизируем паттерн
Автор: WolfHound
Дата: 02.06.11
.

WH>ast ForEach : Expression
WH>{
WH> syntax "foreach" "(" pattern "in" collection ")" body;
WH> pattern : Pattern;
WH> collection : Expression;
WH> body : Expression;
WH>}
WH>typing
WH>{
WH> CollectionItemType(collection.Type, pattern.InType);

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

1. В Немерле паттерн может иметь разный вид.
Так допустим паттерн вида "var is SomeType". В терминах переписывания — это выглядит так:
match (x)
{
  | var is SomeType => $body
  | _ => ()
}

Кроме того это может быть имя переменной, но body, при этом, содержит вхождения match-а, так что в терминах переписывания уже выходит следующая картина:
def var = ...

match (var)
{
  ..$body
}

Так же может быть случай когда паттерн — это просто имя переменной. Тогда в терминах переписывания мы получаем:
{
def var = ...
..$body
}
[/Nemerle]
Другими словами, параметр "pattern" может иметь разный тип в зависимости от контекста. На тип pattern-а влияет как содержимое pattern, так и содержимое body.

Вот фрагмент кода из реализации этого макроса в Н1:
    // build the body of loop (may contain additional matching)
    def build_definition(val)
    {
      match (body)
      {
        | <[ match ($(null)) { ..$cases } ]> =>
          match (iter)
          {
            | <[ $(x : name) ]> when char.IsLower(x.Id[0]) | <[ (..$_) ]> => ()
            | _ => Message.FatalError("only simple names available in pattern of foreach with direct matching")
          }

          <[ def $iter = $val;
             match ($iter) { ..$cases } ]>

        | _ =>
          def mat =
            match (iter)
            {
              | <[ $pat :> $ty ]> => <[ match ($val :> $ty) { | $pat  => $body; () | _ => () } ]>
              | _                 => <[ match ($val)        { | $iter => $body; () | _ => () } ]>
            };
          mat.cases.Iter (fun (x : PT.MatchCase) { x.disable_warnings = true });
          mat
      }
    }


Как видишь тут анализируется содержимое body, и если — это тело match-а то проверяется, что паттерн (который имеет в этой реализации имя iter) содержит простое имя (хотя по уму можно допускать и "_", но это ладно).

Как ты собираешься решать эту проблему?

WH> newscope body add VarsFromPatternType(pattern.Type);

WH> ConvertibleTo(body.Type, #void);
WH> Type = #void;
WH>}


WH>newscope создает пространство имен, вложенное в текущее и типизирует с его помощью указанные выражения. В данном случае body.


Стоп, стоп, стоп! Какое на фиг текущее пространство имен? Ты не забыл, что твой язык ленивый (если вообще носит вычислительную семантику)? Из-за вывода типов то что у тебя содержится в typing на самом деле будет выполняться в черт-знает каком порядке. Скорее всего часть этого дела вообще превратится в некие констрэйны. Таким образом порядок вычислений не определен, а уж говорить о каком-то контексте вообще не приходится.

Ну, и опять же что ты будешь делать в случае который в Н1 называется "direct matching", т.е. когда body содержит cese-ы match-а?

WH>VarsFromPatternType превращает тип паттерна в список переменных.


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

Далее очень интересным вопросом является — как переменные созданный в этом коде будут найдены кодом который будет генерировать тот самый паттерн-матчинг? Другими словами как эти переменные будут связаны с кодом ПМ-а в который в итоге должно все раскрыться?

По сему еще интереснее становится взглянуть на код переписывания. Тут у тебя явно будут несостыковки.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 07.06.11 22:02
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Отсылать к изучении Меркури не стоит. Никто не будет его учить чтобы писать макросы.

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

VD>Потом что это за птичий язык? Что за невнятные сокращения — "semidet", "multi", "mode"? Я так понимаю этот стиль почерпнут из Меркури? Не надо сдирать у него плохоие черты. Имена должны быть внятными и поясняться перед использованием.

Мне просто сейчас лень выдумывать свой синтаксис.

WH>>При помощи бектрекинга перебирает все типы к которым можно привести данный.

VD>Зачем? Почему нельзя просто возвратить список? В общем, ничего не понятно.
И перебирать его руками. Ага, конечно.

VD>Она и не нужна, если это встроенные функции. Но нужно объяснить семантику. Иначе это очередная реинкарнация притчи об утюге. Знаешь такую?

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

VD>Вот и покажи как будет выглядеть реализация этого предиката для коллекции не реализующей IEnumirable. Причем, чем детальнее, тем лучше. При этом загляни в спецификацию C# и повтори ее на своем языке. Интересны:

Пока не закончу с поиском имен я это делать не буду.

VD>Что такое ":: out" тоже не ясно. Это тоже надо пояснять.

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

VD>А где должны располагаться эти "pred"?

В пространстве имен.

VD>Что такое "type"? Это переменная типа? Откуда она взялась? Какова ее область видимости? Мы вводим переменные без объявления? Это противоречит духу немерла. Плюс как отличать введение переменной и использование ранее определенных? Хочется нахватать граблей Руби?

require: collection as x && !x.IsPrimitive // "x" новая переменная типа равная типу collection
require: x has method GetEnumerator() : e // проверяем соответствие паттерну "перечислитель"

Что такое "x" и "e"? Это переменные типов? Откуда они взялась? Какова их область видимости? Мы вводим переменные без объявления? Это противоречит духу немерла. Плюс как отличать введение переменной и использование ранее определенных? Хочется нахватать граблей Руби?


VD>Почему object?

По тому, что IEnumerable возвращает object'ы.

VD>В C# для foreach по IEnumerable используется явное приведение типов. В немерле для тех же целей используется ПМ. Где и как это учитывается?

В ПМ попадает object, а дальше с ним уже ПМ разбирается.

VD>Опять внешние объявления?

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

VD>Где они будут располагаться? Как увидеть связь с макросами?

Рядом с макросами.

VD>1. В Немерле паттерн может иметь разный вид.

Эти два варианта на типизацию вообще никак не повлияют.
Они будут различаться только на этапе кодогенерации.

VD>Кроме того это может быть имя переменной, но body, при этом, содержит вхождения match-а, так что в терминах переписывания уже выходит следующая картина:

Это вариант я просто не рассматривал.
Для этого придется чуток усложнить.
ast ForEach : Expression
{
    syntax "foreach" "(" pattern "in" collection ")" body;
    pattern    : Pattern;
    collection : Expression;
    body       : Expression | MatchBody;
}
typing
{
    CollectionItemType(collection.Type, ItemType);
    pattern.InType = ItemType;
    scope body add VarsFromPatternType(pattern.Type);
    Type = #void;
    {
        body is Expression;
        ConvertibleTo(body.Type, #void);
    |
        body is MatchBody;
        body.InType = ItemType;
        ConvertibleTo(body.Type, #void);
    }
}


VD>Стоп, стоп, стоп! Какое на фиг текущее пространство имен? Ты не забыл, что твой язык ленивый (если вообще носит вычислительную семантику)?

Я все помню.

VD>Из-за вывода типов то что у тебя содержится в typing на самом деле будет выполняться в черт-знает каком порядке. Скорее всего часть этого дела вообще превратится в некие констрэйны. Таким образом порядок вычислений не определен, а уж говорить о каком-то контексте вообще не приходится.

Ну почему же?
У нас есть дерево созданное парсером.
С его помощью можно задать четкую иерархию контекстов.

WH>>VarsFromPatternType превращает тип паттерна в список переменных.

VD>Ее реализация тоже интересна! Это же тоже часть процесса типизации. Убрав его в отдельную функцию ты всего лишь скрыл его с глаз, но не устранил необходимость его писать.
Я ее пока не придумал.
Она очень завязана на поиск имен.

VD>Далее очень интересным вопросом является — как переменные созданный в этом коде будут найдены кодом который будет генерировать тот самый паттерн-матчинг? Другими словами как эти переменные будут связаны с кодом ПМ-а в который в итоге должно все раскрыться?

Переменные порождаются из определенных узлов АСТ.
Те мы и при типизации знаем, где имя объявлено.
И при кодогенерации мы при создании переменных генерируем их из исходных имен.
И во вложенном коде будет известно, с каким объявлением мы связали данное имя.
После чего мы это еще разок проверим. Чтобы убедиться, что разработчик макроса не накосячил.

VD>По сему еще интереснее становится взглянуть на код переписывания. Тут у тебя явно будут несостыковки.

RewriteForeachBody(fe : ForEach) : Expression
{
    def body = match (fe.Body)
    {
        | body is Expression => body
        | body is MatchBody  => <[ match (item) $body ]>
    }
    match (fe.pattern)
    {
        | pattern is VarPattern =>
            <[
                def $(pattern.Name) = item;
                $body
            ]>

        | pattern =>
            <[
                match (item)
                {
                    | $(pattern) => $body
                    | _          => ()
                }
            ]>
    }
}

rewriter GenericIEnumirableForEach for ForEach
when ConvertibleTo(collection.Type, IEnumerable[_]);
{
    <[
        using (enum = ($collection).GetEnumerator())
        {
            while (enum.MoveNext())
            {
                def item = enum.Current;
                $(RewriteForeachBody(this));
            }
        }
    ]>
}

RewriteForeachBody один на всех. VarPattern см тут
Автор: WolfHound
Дата: 02.06.11
.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.06.11 15:04
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Это вариант я просто не рассматривал.

WH>Для этого придется чуток усложнить.
WH>
WH>ast ForEach : Expression
WH>{
WH>    syntax "foreach" "(" pattern "in" collection ")" body;
WH>    pattern    : Pattern;
WH>    collection : Expression;
WH>    body       : Expression | MatchBody;
WH>}
WH>typing
WH>{
WH>    CollectionItemType(collection.Type, ItemType);
WH>    pattern.InType = ItemType;
WH>    scope body add VarsFromPatternType(pattern.Type);
WH>    Type = #void;
WH>    {
WH>        body is Expression;
WH>        ConvertibleTo(body.Type, #void);
WH>    |
WH>        body is MatchBody;
WH>        body.InType = ItemType;
WH>        ConvertibleTo(body.Type, #void);
WH>    }
WH>}
WH>


То что ты демонстрируешь — это банальное очковтирательство. Погляди внимательно на мой вариант, а еще лучше на "тот ужасный код" что есть в Н1. Там ест куча сообщений об ошибках. Без них все это совершенно не интересно. Тоже самое относится к типизации паттернов. Там вообще какие-то игрушечные потягужки не имеющие ничего общего с реальностью.

VD>>По сему еще интереснее становится взглянуть на код переписывания. Тут у тебя явно будут несостыковки.

WH>
WH>RewriteForeachBody(fe : ForEach) : Expression
WH>{
WH>    def body = match (fe.Body)
WH>    {
WH>        | body is Expression => body
WH>        | body is MatchBody  => <[ match (item) $body ]>
WH>    }
WH>    match (fe.pattern)
WH>    {
WH>        | pattern is VarPattern =>
WH>            <[
WH>                def $(pattern.Name) = item;
WH>                $body
WH>            ]>

WH>        | pattern =>
WH>            <[
WH>                match (item)
WH>                {
WH>                    | $(pattern) => $body
WH>                    | _          => ()
WH>                }
WH>            ]>
WH>    }
WH>}

WH>rewriter GenericIEnumirableForEach for ForEach
WH>when ConvertibleTo(collection.Type, IEnumerable[_]);
WH>{
WH>    <[
WH>        using (enum = ($collection).GetEnumerator())
WH>        {
WH>            while (enum.MoveNext())
WH>            {
WH>                def item = enum.Current;
WH>                $(RewriteForeachBody(this));
WH>            }
WH>        }
WH>    ]>
WH>}
WH>


И что мы видим? Все что было сделано в "типизации" тупо выброшено на свалку истории и производится переписывание. Теперь типизация будет производиться еще раз. Результаты предыдущей можно смело выкинуть, так как никто не гарантирует их корректности.

Получается, что мы сделали ряд никому не нужных действий.

Плюс остается вопрос — как генерируется TAST (конечный код)? Ведь именно он нужен в конечном итоге.

WH>RewriteForeachBody один на всех.


Это и сейчас так.

Вот только у тебя нет ни одного сообщения об ошибке. А именно они делают макрос удобным в использовании. Добавь их и твой код многократно разбухнет.

WH> VarPattern см тут
Автор: WolfHound
Дата: 02.06.11
.


Там вообще какая-то каша.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 09.06.11 15:58
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>То что ты демонстрируешь — это банальное очковтирательство. Погляди внимательно на мой вариант, а еще лучше на "тот ужасный код" что есть в Н1. Там ест куча сообщений об ошибках. Без них все это совершенно не интересно.

Ну давай разбираться.
Может я плохо смотрел, но я нашёл ровно 3 сообщения, которые генерирует foreach.

Message.FatalError($<#the syntax is ' "foreach" "(" name "in" collection (with indexName)? ")" body ', got $e#>);
Это не нужно, ибо у нас нормальный парсер.

Message.FatalError("only simple names available in pattern of foreach with direct matching")
Это не нужно, ибо я сделал, так что матчить можно и там и там.
Поведение ровно такое же, как с функциями.
За одно у меня автоматом получилась возможность писать _ вместо имени переменной в foreach.

Осталось:
Message.Error($"collection in foreach must be an array or type implementing enumerator pattern, $guess");
Message.Hint("try specifing the type directly using 'expr : SomeType'");

Это можно переписать 1 в 1.
    CollectionItemType(collection.Type, ItemType) else
        error "collection in foreach must be an array or type implementing enumerator pattern"
        hint "try specifing the type directly using 'expr : SomeType'";

Итого +2 строки.
Как добавить guess я еще подумаю. Но ИМХО не очень-то он и нужен.

VD>Тоже самое относится к типизации паттернов. Там вообще какие-то игрушечные потягужки не имеющие ничего общего с реальностью.

Там есть все что нужно.
Просто нужно понимать, что на самом деле все сильно проще, чем тебе кажется.
Ибо ты смотришь на задачу с точки зрения того жуткого императива в компиляторе Н1 за которым не видно леса.
Я же оставляю только саму суть.
Жуткий императив будет генерировать компилятор.

VD>И что мы видим? Все что было сделано в "типизации" тупо выброшено на свалку истории и производится переписывание. Теперь типизация будет производиться еще раз. Результаты предыдущей можно смело выкинуть, так как никто не гарантирует их корректности.

Никуда ничего не будет выкинуто.
Основная типизация была внутри body.
Он вся сохраниться.
Типизация pattern'а тоже сохранится.
Типизировать будут только сгенерированные конструкции.

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

VD>Получается, что мы сделали ряд никому не нужных действий.

Это твои фантазии.

VD>Плюс остается вопрос — как генерируется TAST (конечный код)? Ведь именно он нужен в конечном итоге.

1)Даже без переписывания это уже TAST. Ибо у меня все типизаронанно.
2)Переписывание будет происходить пока не останется TAST понятный текущему бекенду.

И главное в моем подходе TAST в том виде как понимаешь, его ты нет.
Это просто лишняя сущность.
Ты хочешь сделать немерле++. Я хочу действительно универсальное решение.

Пойми никто не мешает сделать некое стандартное TAST. И это будет твой вариант. Я предлагаю строгое надмножество того что хочешь сделать ты.

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

WH>> VarPattern см тут
Автор: WolfHound
Дата: 02.06.11
.

VD>Там вообще какая-то каша.
А может ты, наконец, сформулируешь внятный вопрос?
Там все просто.
InType это тип выражения которое матчит паттерн.
Type это набор имен переменных и их типов которые связываются внутри паттерна.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.06.11 13:47
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>>> VarPattern см тут
Автор: WolfHound
Дата: 02.06.11
.

VD>>Там вообще какая-то каша.
WH>А может ты, наконец, сформулируешь внятный вопрос?

ОК. Начать надо с того чтобы ты внимально прочитал вот это
Автор(ы): Михаил Купаев (Kupaev)
Дата: 14.03.2005
Поиск в Google по словам "как писать статьи" выдает 664 страницы. Статьи с таким названием писали столь уважаемые люди, как Г.А. Шенгели, А.А.Шалыто и др. Но в целом, 664 страницы — это, конечно, перебор. Понятно, что большая часть этого моря писанины сочинена людьми, писать статьи не умеющими. Если бы они умели писать статьи, они их писали бы, а не учили других. Признаюсь честно – я не знаю, как надо писать статьи. Зато за время своего редакторства я насмотрелся на такое количество уродцев, которого хватило бы на пару питерских Кунсткамер, и еще осталось бы на несколько курортных выставок. Поэтому я достаточно хорошо представляю себе, чего при этом делать не нужно. Вот об этом-то я и попытаюсь рассказать...
. Особенно раздел Телепатия на марше, или сага об утюгах
Автор(ы): Михаил Купаев (Kupaev)
Дата: 14.03.2005
Поиск в Google по словам "как писать статьи" выдает 664 страницы. Статьи с таким названием писали столь уважаемые люди, как Г.А. Шенгели, А.А.Шалыто и др. Но в целом, 664 страницы — это, конечно, перебор. Понятно, что большая часть этого моря писанины сочинена людьми, писать статьи не умеющими. Если бы они умели писать статьи, они их писали бы, а не учили других. Признаюсь честно – я не знаю, как надо писать статьи. Зато за время своего редакторства я насмотрелся на такое количество уродцев, которого хватило бы на пару питерских Кунсткамер, и еще осталось бы на несколько курортных выставок. Поэтому я достаточно хорошо представляю себе, чего при этом делать не нужно. Вот об этом-то я и попытаюсь рассказать...
.
Потом нужно внимательно изучить вот это. После этого надо сделать еще один подход и описать реальную реализацию типизации паттернов в которой будут все (или хотя бы большая часть) сообщения об ошибках что есть в последней ссылке и преобразование вот в этот вариант (как результат процесса типизации):
  public variant Pattern : Located
  {
    | Wildcard
    | As          { pat : Pattern; decl : LocalValue; }
    | HasType     { typ : FixedType; }
    | Tuple       { args : list [Pattern]; }
    | Record      { args : list [IMember * Pattern]; }
    | Application { name : TypeInfo; arg : Pattern; }
    | Enum        { fld : IField; val : Nemerle.Compiler.Literal; }
    | Literal     { lit : Nemerle.Compiler.Literal; }
    | Error

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

Далее. Почему у тебя там какие-то разные виды типов? Тип выражения и тип паттерна должен быть единым. И между ними должна производиться унификация.

Теперь о ConvertibleTo. Наличие неявного преобразования типов и возможность унификации — это не одно и тоже. Понятие преобразование типов включает в себя унификацию, но не наоборот. С точки зрения типизации конечно можно ввести некий специальный констрэйн — нечто вроде унификации с признаком необходимости конвертации типов. Но в любом случае при генерации TAST в местах где использовано ConvertibleTo должен проводиться анализ и подставляться некоторый код конвертации. Например, вызов функций неявного преобразования типов. Соответственно вопросов два.
1. Как таки будет выглядеть генерация TAST?
2. Какова будет связь между генерацией TAST и типизацией? Не будет ли там дублирования.

Отдельная претензия к синтаксису. Прологовские правила (они же паттерн-матчинг в обе стороны) основаны на том факте, что переменные имеют отличия в синтаксисе от атомов и термов. По сему в твоих примерах постоянный конфликт меду именами вводимыми в паттернах и внешними именами. Этот конфликт надо разрешать. То что показывал я такого конфликта не имеет, так как мои паттерны не могут ссылаться на внешние переменные. У меня в коде "collection as x" — x — это всегда новая переменная. У тебя же явного синтаксиса введения переменных нет, а значит на лицо конфликт.

Теперь про in/out. Это не понятно, да и не красиво. out-тип может быть только один. По сему описывать явно out-тип бессмысленно. Само применение in/out выглядит дико, непривычно и многословно. По сему имеет смысл всегда иметь один out-тип и использовать для его идентификации стандартный синтаксис. Идентифицировать out-типы правил можно по их именам (как в моих примерах). in-типы надо как-то описывать. Но это уже больше похоже на описание параметров.

WH>Там все просто.

WH>InType это тип выражения которое матчит паттерн.
WH>Type это набор имен переменных и их типов которые связываются внутри паттерна.

То что ты называешь типом паттерна — это не тип, а нечто вроде вариантного типа Pattern описанного мной выше. Вот его ты и должен получить. Причем со всеми деталями. А их там не мало.
А то что паттерн порождает еще и список переменных — это уже к типу отношения не имеет. Это имеет отношение к списку переменных, разрешению имен и т.п., но не к типизации.

Типизация паттерна должна связывать все выражение в единое дерево. Скажем, если у нас есть:
match (x)
{
  | pattern1 => e1
  | pattern2 => e2
}

то pattern1 и pattern2 должны иметь свои типы. И тип "x" должен быть связан с типами этих паттернов весьма не тривиальным образом. Нетривиальность проистекает из-за того, что паттерны могут up-cast-ить выражения. Причем up-cast-иться могут не только сами паттерны, но и их части. Возможность такого up-cast-та нужно проверять во время типизации.

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

Ну, а то что ты продемонстрировал никак не тянет на реальную типизацию паттернов. Так что внимательно изучи то как типизация паттернов делается сейчас и попробуй создать более детальный пример в котором будет генерация TAST, выдача всех возможных сообщений об ошибках, проверка возможности up-cast-ов и т.п.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.06.11 14:56
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Ну давай разбираться.

WH>Может я плохо смотрел, но я нашёл ровно 3 сообщения, которые генерирует foreach.

А ты смотри спецификацию C#. Там прямо описаны сообщения об ошибках которые надо выдавать и когда их надо выдавать.

The compile-time processing of a foreach statement first determines the collection type, enumerator type and element type of the expression. This determination proceeds as follows:
• If the type X of expression is an array type then there is an implicit reference conversion from X to the System.Collections.IEnumerable interface (since System.Array implements this interface). The collection type is the System.Collections.IEnumerable interface, the enumerator type is the System.Collections.IEnumerator interface and the element type is the element type of the array type X.
• Otherwise, determine whether the type X has an appropriate GetEnumerator method:
o Perform member lookup on the type X with identifier GetEnumerator and no type arguments. If the member lookup does not produce a match, or it produces an ambiguity, or produces a match that is not a method group, check for an enumerable interface as described below. It is recommended that a warning be issued if member lookup produces anything except a method group or no match.
o Perform overload resolution using the resulting method group and an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, check for an enumerable interface as described below. It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.
o If the return type E of the GetEnumerator method is not a class, struct or interface type, an error is produced and no further steps are taken.
o Member lookup is performed on E with the identifier Current and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a public instance property that permits reading, an error is produced and no further steps are taken.
o Member lookup is performed on E with the identifier MoveNext and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a method group, an error is produced and no further steps are taken.
o Overload resolution is performed on the method group with an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, or its return type is not bool, an error is produced and no further steps are taken.
o The collection type is X, the enumerator type is E, and the element type is the type of the Current property.
• Otherwise, check for an enumerable interface:
o If there is exactly one type T such that there is an implicit conversion from X to the interface System.Collections.Generic.IEnumerable<T>, then the collection type is this interface, the enumerator type is the interface System.Collections.Generic.IEnumerator<T>, and the element type is T.
o Otherwise, if there is more than one such type T, then an error is produced and no further steps are taken.
o Otherwise, if there is an implicit conversion from X to the System.Collections.IEnumerable interface, then the collection type is this interface, the enumerator type is the interface System.Collections.IEnumerator, and the element type is object.
o Otherwise, an error is produced and no further steps are taken.


WH>Message.FatalError($<#the syntax is ' "foreach" "(" name "in" collection (with indexName)? ")" body ', got $e#>);

WH>Это не нужно, ибо у нас нормальный парсер.

+1

WH>Message.FatalError("only simple names available in pattern of foreach with direct matching")

WH>Это не нужно, ибо я сделал, так что матчить можно и там и там.

А, ну, да. Сделал магическую функцию которая виртуально делает все что надо и типа решил задачу.

WH>Осталось:

WH>Message.Error($"collection in foreach must be an array or type implementing enumerator pattern, $guess");
WH>Message.Hint("try specifing the type directly using 'expr : SomeType'");

WH>Это можно переписать 1 в 1.

WH>
WH>    CollectionItemType(collection.Type, ItemType) else
WH>        error "collection in foreach must be an array or type implementing enumerator pattern"
WH>        hint "try specifing the type directly using 'expr : SomeType'";
WH>


Я так и не увидел полноценного анализа реализации паттерна перечислитель. Только в нем будет штуки 3 сообщения об ошибке.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 10.06.11 16:12
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>ОК. Начать надо с того чтобы ты внимально прочитал вот это
Автор(ы): Михаил Купаев (Kupaev)
Дата: 14.03.2005
Поиск в Google по словам "как писать статьи" выдает 664 страницы. Статьи с таким названием писали столь уважаемые люди, как Г.А. Шенгели, А.А.Шалыто и др. Но в целом, 664 страницы — это, конечно, перебор. Понятно, что большая часть этого моря писанины сочинена людьми, писать статьи не умеющими. Если бы они умели писать статьи, они их писали бы, а не учили других. Признаюсь честно – я не знаю, как надо писать статьи. Зато за время своего редакторства я насмотрелся на такое количество уродцев, которого хватило бы на пару питерских Кунсткамер, и еще осталось бы на несколько курортных выставок. Поэтому я достаточно хорошо представляю себе, чего при этом делать не нужно. Вот об этом-то я и попытаюсь рассказать...
. Особенно раздел Телепатия на марше, или сага об утюгах
Автор(ы): Михаил Купаев (Kupaev)
Дата: 14.03.2005
Поиск в Google по словам "как писать статьи" выдает 664 страницы. Статьи с таким названием писали столь уважаемые люди, как Г.А. Шенгели, А.А.Шалыто и др. Но в целом, 664 страницы — это, конечно, перебор. Понятно, что большая часть этого моря писанины сочинена людьми, писать статьи не умеющими. Если бы они умели писать статьи, они их писали бы, а не учили других. Признаюсь честно – я не знаю, как надо писать статьи. Зато за время своего редакторства я насмотрелся на такое количество уродцев, которого хватило бы на пару питерских Кунсткамер, и еще осталось бы на несколько курортных выставок. Поэтому я достаточно хорошо представляю себе, чего при этом делать не нужно. Вот об этом-то я и попытаюсь рассказать...
.

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

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

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

VD>Потом нужно внимательно изучить вот это.

И что я должен увидеть в этой куче деревьев? Леса за ними не видно.

VD> После этого надо сделать еще один подход и описать реальную реализацию типизации паттернов в которой будут все (или хотя бы большая часть) сообщения об ошибках что есть в последней ссылке и

Там есть все ошибки, которые можно сообщить для тех паттернов, которые там есть.
Остальным паттернам нужен поиск имен.
Кстати OrPattern и AndPattern в немерле просто отсутствуют.

VD>преобразование вот в этот вариант (как результат процесса типизации):

1)Это настолько тривиально, что даже скучно.
2)Как результат процесса переписывания в более низкоуровневый язык.

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

VD>Именно описанный выше вариант должен появиться в конце процесса типизации,

Он кстати очень убог.

VD>Далее. Почему у тебя там какие-то разные виды типов? Тип выражения и тип паттерна должен быть единым. И между ними должна производиться унификация.

Не должна.
Ты не видишь за деревьями леса и не понимаешь суть вещей.
Прочитай Type Safe Pattern Combinators, by Morten Rhiger.
Там последовательно и очень доходчиво объясняется, откуда берется тип паттерна.
Я просто пошёл чуть дальше и довел это до логического конца, плюс избавился от плясок вокруг системы типов хаскеля.
Если посмотреть, то наверняка можно найти много чего, что по-хорошему должно иметь свои типы.

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

Ну, вставит их очередной проход трансформации.
Делов то.
Я вообще не понимаю, что тут обсуждать.

VD>Отдельная претензия к синтаксису.

Повторяю сотый раз: Синтаксис меня на донном этапе не волнует. Совсем.

VD>Теперь про in/out. Это не понятно, да и не красиво. out-тип может быть только один.

Это не правда.
Выходных параметров у предиката может быть больше одного.

VD>То что ты называешь типом паттерна — это не тип, а нечто вроде вариантного типа Pattern описанного мной выше. Вот его ты и должен получить. Причем со всеми деталями. А их там не мало.

Ничего ты не понял. И что самое печально даже не попытался.
Тип паттерна это одно. Твой вариантный тип другое.
Разница такая же, как между int и деревом выражения 1 + 2 * 3.

VD>А то что паттерн порождает еще и список переменных — это уже к типу отношения не имеет. Это имеет отношение к списку переменных, разрешению имен и т.п., но не к типизации.

1)Это и есть тип паттерна.
Или более точно
Тип -> Словарь[Имя, Тип]

Те паттрен [a, b] имеет свой самостоятельный тип list[T] -> { a : T; b : T; }
Ни с каким выражением его унифицировать нельзя. Это всё равно что унифицировать яблоки с жирафами.

2)Разрешение имен это неотъемлемая часть типизации.

VD>Типизация паттерна должна связывать все выражение в единое дерево. Скажем, если у нас есть:

Не путай типизацию паттерна и типизацию match'а. Это разные вещи.

VD>то pattern1 и pattern2 должны иметь свои типы. И тип "x" должен быть связан с типами этих паттернов весьма не тривиальным образом. Нетривиальность проистекает из-за того, что паттерны могут up-cast-ить выражения. Причем up-cast-иться могут не только сами паттерны, но и их части. Возможность такого up-cast-та нужно проверять во время типизации.

Искаропки.
Просто вместо
lPattern.InType = InType;
Нужно писать
ConvertibleTo(InType, lPattern.InType);

VD>Таким образом то что ты называешь типом паттерна на самом деле является уже частью TAST.

Нет. Тип паттерна это тип паттерна.

VD>Ну, а то что ты продемонстрировал никак не тянет на реальную типизацию паттернов.

Просто ты не понял что это.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.06.11 16:20
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


VD>>ОК. Начать надо с того чтобы ты внимально прочитал вот это
Автор(ы): Михаил Купаев (Kupaev)
Дата: 14.03.2005
Поиск в Google по словам "как писать статьи" выдает 664 страницы. Статьи с таким названием писали столь уважаемые люди, как Г.А. Шенгели, А.А.Шалыто и др. Но в целом, 664 страницы — это, конечно, перебор. Понятно, что большая часть этого моря писанины сочинена людьми, писать статьи не умеющими. Если бы они умели писать статьи, они их писали бы, а не учили других. Признаюсь честно – я не знаю, как надо писать статьи. Зато за время своего редакторства я насмотрелся на такое количество уродцев, которого хватило бы на пару питерских Кунсткамер, и еще осталось бы на несколько курортных выставок. Поэтому я достаточно хорошо представляю себе, чего при этом делать не нужно. Вот об этом-то я и попытаюсь рассказать...
. Особенно раздел Телепатия на марше, или сага об утюгах
Автор(ы): Михаил Купаев (Kupaev)
Дата: 14.03.2005
Поиск в Google по словам "как писать статьи" выдает 664 страницы. Статьи с таким названием писали столь уважаемые люди, как Г.А. Шенгели, А.А.Шалыто и др. Но в целом, 664 страницы — это, конечно, перебор. Понятно, что большая часть этого моря писанины сочинена людьми, писать статьи не умеющими. Если бы они умели писать статьи, они их писали бы, а не учили других. Признаюсь честно – я не знаю, как надо писать статьи. Зато за время своего редакторства я насмотрелся на такое количество уродцев, которого хватило бы на пару питерских Кунсткамер, и еще осталось бы на несколько курортных выставок. Поэтому я достаточно хорошо представляю себе, чего при этом делать не нужно. Вот об этом-то я и попытаюсь рассказать...
.

WH>Ты тоже иди что-нибудь прочитай на тему того как не считать других идиотами.

Я что вижу то и говорю. Вижу несвязанное изложение с кучей утюгов и говорю об этом.

WH>Ты не понимаешь что я пишу по тому что твоя голова забита бессистемными стериотипами того как сделано у других.


Ты тоже иди что-нибудь прочитай на тему того как не считать других идиотами. (с)

WH>Когда ты видишь что-то что не стыкуется с тем что ты уже заучил ты тут же включаешь режим "это все бред" и даже не пытаешься понять что тебе пишут.


Я тебе всего лишь заметил, что твои описания не полны, имеют кучу неописанных деталей и довольно наивны.
Можешь меня не слушать. Только задумайся над очень простым вопросом. Почему на твои писания отвечаю только я? Больше ведь никто ничего по делу не сказал. Очевидный ответ на этот вопрос — никто ничего не понял из твоих слов.

Так что, в моем лице, видишь как раз видишь единственного читателя кто тебя пытается понять. И вместо того чтобы все время переходить на обсуждение моей личности тебе бы стоило бы поискать бревно в своем глазу.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.06.11 16:24
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>Потом нужно внимательно изучить вот это.

WH>И что я должен увидеть в этой куче деревьев? Леса за ними не видно.

Учить читать чужой код. Не в силах понять его "с листа", создай простенькие паттерны и посмотри их типизацию под отладчиком.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.06.11 17:09
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>Ну, а то что ты продемонстрировал никак не тянет на реальную типизацию паттернов.

WH>Просто ты не понял что это.

Короче, мне эти приперательства надоели. Предлагаю поступить следующим образом. Создай прототип своего типизатора паттернов (как более-менее обособленной задачи) в виде макроса Н1. Там вся нужная инфраструктура есть. Все остальное навернешь сверху. Я тебя могу проконсультировать по деталям типизации Н1. В общем, как с ПегГраммаром.

Будет, код — будет на что смотреть и что обсуждать.

Макры Н1 пашут во время типизации. Так что это позволяется вклиниться в процесс типизации. В них можно узнать все типы окружающих выражений.

Там ты покажешь во что все это выльется. Задача очень проса — получить в итоге аналог типизатора паттернов Н1, но в виде макроса. На входе будет код match-а, а на выходе должен быть класс Match_case:
  [Record]
  public class Match_case
  {
    public mutable patterns : list [Pattern * TExpr * list [LocalValue * TExpr]];
    public mutable body : TExpr;
    public mutable disable_warnings : bool;
  }


Вот на этом примере ты и покажешь все части (типизацию, понижение/переписывание, генерация сообщений об ошибках и т.п.).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 10.06.11 17:17
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Я тебе всего лишь заметил, что твои описания не полны, имеют кучу неописанных деталей и

Разумеется, не полны. Я еще не до конца все продумал.

VD>довольно наивны.

Их "наивность" происходит из того что ты ничего не понял.
Одно то, что ты путаешь тип паттерна с TAST паттерна говорит о том, как ты "пытаешься" понять.
Заметь, ты не сказал "зачем" ты сразу сказал "не нужно".

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

А может ты вместо того чтобы кричать "не нужно" подумаешь зачем я ввел тип паттерна?
Почему я постоянно говорю, что типизация это часть синтаксического анализа?
...
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 10.06.11 17:17
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Учить читать чужой код. Не в силах понять его "с листа", создай простенькие паттерны и посмотри их типизацию под отладчиком.

Зачем мне читать этот код?
Я тебе в прошлом сообщении дал ссылку на статью где описывается, как делать паттрены на комбинаторах.
Там описываются типы паттернов. И как сложный паттерн собирать из простых. И то, как при этом меняется тип паттерна.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 10.06.11 17:32
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Короче, мне эти приперательства надоели. Предлагаю поступить следующим образом. Создай прототип своего типизатора паттернов (как более-менее обособленной задачи) в виде макроса Н1. Там вся нужная инфраструктура есть. Все остальное навернешь сверху. Я тебя могу проконсультировать по деталям типизации Н1. В общем, как с ПегГраммаром.


Писать то во что раскрывается мой ДСЛ руками я не буду. Ибо это всё равно, что тот код, который генерируется PegGrammar руками долбить.

VD>Макры Н1 пашут во время типизации. Так что это позволяется вклиниться в процесс типизации. В них можно узнать все типы окружающих выражений.

И это плохо.
Это смешение слоёв. Ребята смешали синтаксис и семантику. А ты вместо того чтобы исправить этот бардак настаиваешь на том чтобы я его повторил.
Это типа как вместо MVVM писать SQL запросы в обработчике события кнопки.
Вроде работает но по факту поддерживать невозможно.

VD>Вот на этом примере ты и покажешь все части (типизацию, понижение/переписывание, генерация сообщений об ошибках и т.п.).

Покажу.
Но только на отдельном прототипе.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 10.06.11 17:43
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А, ну, да. Сделал магическую функцию которая виртуально делает все что надо и типа решил задачу.

И что в RewriteForeachBody магического?
Она генерирует код, который ждет, что будет локальная переменная item в которой лежит текущее значение.

VD>Я так и не увидел полноценного анализа реализации паттерна перечислитель. Только в нем будет штуки 3 сообщения об ошибке.

Тебе ещё сколько раз повторить, чтобы ты, наконец, понял, что его не будет, пока не будет поиска имен?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.06.11 18:29
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Писать то во что раскрывается мой ДСЛ руками я не буду. Ибо это всё равно, что тот код, который генерируется PegGrammar руками долбить.


Пиши не руками. Вся сила макросов и т.п. в твоих руках.
Пустые слова надоели.

VD>>Макры Н1 пашут во время типизации. Так что это позволяется вклиниться в процесс типизации. В них можно узнать все типы окружающих выражений.

WH>И это плохо.
WH>Это смешение слоёв...

Да ты достало своей пропагандой. Отвлекись о нее. Для целей создания прототипа это то что нужно. Ты из своей макры сможешь достать АПИ типизации и построить на его базе свой ДСЛ (в сто раз проще нежели писать с нуля).

Просто смотри на на это как на прототип который принципиально пойдет в помойку.

WH>Ребята смешали синтаксис и семантику.


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

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

WH> А ты вместо того чтобы исправить этот бардак настаиваешь на том чтобы я его повторил.


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

WH>Это типа как вместо MVVM писать SQL запросы в обработчике события кнопки.


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

WH>Вроде работает но по факту поддерживать невозможно.


Твой код тоже кроме тебя мало кто поддерживать может.

VD>>Вот на этом примере ты и покажешь все части (типизацию, понижение/переписывание, генерация сообщений об ошибках и т.п.).

WH>Покажу.
WH>Но только на отдельном прототипе.

А кому нужны игрушки? Да и писать ты свой прототип с нуля будешь пару лет. Ты вот уже 4 месяца никак расширяемость не прикрутишь к парсеру. А тут задача явно по объемнее будет.

В макросе же ты мог бы получить готовый движок унифицации типов учитывающий подтипы и т.п. Плюс весь парсинг за тебя уже сделан будет. Ну, а главное, что результат твоей работы будет передаваться реальному компилятору и его можно будет опробовать на практике. Возможно даже заменить им тот код что есть сейчас.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.06.11 18:31
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>А, ну, да. Сделал магическую функцию которая виртуально делает все что надо и типа решил задачу.

WH>И что в RewriteForeachBody магического?

VarFromPattern или как она там у тебя называлась?

VD>>Я так и не увидел полноценного анализа реализации паттерна перечислитель. Только в нем будет штуки 3 сообщения об ошибке.

WH>Тебе ещё сколько раз повторить, чтобы ты, наконец, понял, что его не будет, пока не будет поиска имен?

Ну, значит и говорить пока не о чем.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 10.06.11 19:25
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Да ты достало своей пропагандой. Отвлекись о нее. Для целей создания прототипа это то что нужно. Ты из своей макры сможешь достать АПИ типизации и построить на его базе свой ДСЛ (в сто раз проще нежели писать с нуля).

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

VD>Просто смотри на на это как на прототип который принципиально пойдет в помойку.

Дадада. И потом гляди на ту гору кода, которая получилась при борьбе с АПИ немерла ты скажешь "Я же говорил что твой подход фигня!".

VD>Этим ты тоже достал. Твои воззрения на синтаксис и семантику воспринимаешь нормально только ты один.

Не только.
Люди, которые копали вопрос действительно глубоко, все как один со мной согласны.
Не надо молиться на дракона. Он хармфул.

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

И разве это повод перенести бардак в новую версию, которая делается с нуля?

VD>Твой код тоже кроме тебя мало кто поддерживать может.

Да ладно. Хардкейс без проблем вставляет, что ему нужно.
И я на него не ругаюсь, ибо грамотно вставляет. За ним ничего подчищать не приходится.

VD>А кому нужны игрушки? Да и писать ты свой прототип с нуля будешь пару лет. Ты вот уже 4 месяца никак расширяемость не прикрутишь к парсеру. А тут задача явно по объемнее будет.

Я ее просто не пишу.
Мотивации нет. Совсем.
А так как этот прототип без расширяемости не взлетит то я и ее заодно сделаю.

VD>В макросе же ты мог бы получить готовый движок унифицации типов учитывающий подтипы и т.п.

Тоже мне рокетсайнс.

VD>Плюс весь парсинг за тебя уже сделан будет.

Немерловый парсер пусть идет лесом. Это ужОс-ужОс. Я с ним работать не хочу. Совсем.

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

Не взлетит. Другая философия.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 10.06.11 19:28
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>VarFromPattern или как она там у тебя называлась?

Тип паттерна (ага тот самый, которого типа нет ) это список пар имя и тип.
Что сложного в том чтобы превратить такие пары в переменные?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[12]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.06.11 20:08
Оценка:
Здравствуйте, artelk, Вы писали:

A>На сколько я понял, твой подход заключается в том, что должен быть базовый язык, для которого реализован типизатор и кодогенераторы под разные платформы. Плюс будут макросы, разворачивающиеся в этот базовый язык (и\или меняющие куски AST). Если кому-то захочется написать свой DSL или вообще свой отдельный язык, ему нужно просто написать макрос(ы)-транслятор(ы), преобразующие этот язык в AST базового языка. После этого он автоматом получит возможность компилировать программы, причем под различные платформы и т.п. Так?


Так.

A>Подход WH, на сколько я понял — это сделать настоящий парсер подмножества КЗ языков, покрывающее, по крайней мере, строготипизированные языки программирования. Обычный подход — это для КЗ языка программирования выделить КС-ный надъязык, реализовать для него парсер с построением AST и следующим этапом уже вручную пройтись по полученному AST, достраивая "семантические" связи, расставляя типы и выявляя ошибки, которые не смог отловить парсер. Под "семантикой" тут подразумевается как раз та часть языка, которая не покрывается грамматикой используемого в данном конкретном случае КС-ного надъязыка.


Не савсем. Рассказы про КС-парсеры — это скажем так — пиар.

На самом деле вся разница между нашими подходами заключается только в том допускается ли преобразование нетипизированного АСТ или нет. В планах WH точно так же есть КС-парсер который выдает на выходе нетипизированное АСТ.

WH предлагает сделать то что не сделано у других — кроме генерируемого (но расширяемого) парсера он предлагает сделать генерируемый и расширяемый типизатора. И вот тандем парсера и типизатора он и называет КЗ-парсером (точнее не называет, а подразумевает, так как в слух он это не произносил).

Собственно я целиком и полностью за то чтобы автоматизировать и стандартизировать то что все не прогрессивное человечество (на зло Вольфхануду) называет семантическим анализом. И с идеей создания DSL-я типизации и разрешения имен я тоже целиком и полностью согласен. Это снимает оставшиеся вопросы которые я и сам предъявлял к своей идее.

A>Если же делать "настоящий" парсер, разбирающий КЗ язык программирования, то в этом втором этапе надобность отпадает. Но в таком подходе типы выражений становятся сущностями этапа парсинга и они должны задаваться прямо как часть грамматики, что и пытается сделать WH (если я в чем-то не прав — скажите, плиз). Затея выглядит очень амбициозно.


Да нет. Все в сто раз проще. Хотя затея и правда амбициозная. Другие нас не интересуют .
Про КЗ-языки — это WH тереотезировал. Просто по сути если типизация автоматизировна, то можно рассматривать это дело как КЗ-парсер. Так что это просто терминологический вопрос.

A>В таком подходе базовый язык, в который все транслируется, необязателен.


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

Идея лепить все с нуля для каждого языка — это заранее провальная идея.

A>Если и делать такой базовый язык, то он будет описан теми же средствами, что используются при определении макросов (а вообще, ими и исчерпываться).


Ну, дык, а почему нет то? Конечно его же средствами. Только он будет стандартизирован, полон, оттестирован и т.п. А уж то что я называю TAST — это вообще типизированный ассемблер. Его задача только быть моделью для генераторов кода.

A>Отдельный типизатор тоже не нужен, т.к. сам он будет описан на том-же mercury-подобном языке и будет децентрализован и "размазан" по определениям макросов.


Ну, в общем-то — да. Ели принять идею генерации кода типизацтора по ДСЛ (а она мне нравится), то код типизатора будет размазан по отдельным макрам.

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

A>Добавляя новый макрос и задавая правила его типизации мы тем самым разширяем "общий" типизатор этими правилами.


Ну, да. Как-то так. Если прокатит, конечно.

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


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

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

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


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

Для проверки концепций достаточно создать маленький кусочек. Но чтобы его создать нужно сделать кучу побочной работы. Тот же "специализированный Меркури" включает в себя довольно много сложного кода большая часть которого есть в Н1. Это, в первую очередь, движок унификации который позволит унифицировать не просто термы (как в прологоподобных языках вроде Меркури), а типы с поддержкой подтипов. Это не маленький такой (и не самый простой) код. Только на его отдадку можно убить несколько месяцев. А на базе солвера из Н1 его можно создать очень быстро и просто. Он, конечно, будет далек от идеала по производительности, но для прототипа этого и не надо.

Если посмотреть на задачу абстрактно, то по сути тайпер будет в любом случае. Только в одном случае он размещен в одном классе и использует внешнее АСТ, а в другом его код размазан по "определению АСТ" (макросам) и описан на специальном ДСЛ-е.

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

А вот писать прототип с нуля — это очень опасное занятие. Энтузиазм имеет особенность уменьшаться обратно пропорционально размеру задачи. И запалу может просто не хватить. А амбициозные идеи они никому не нужны. Нужны амбициозные реализации.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Размышления о типизаторе для Н2
От: artelk  
Дата: 27.06.11 12:27
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


A>>Подход WH, на сколько я понял — это сделать настоящий парсер подмножества КЗ языков,

WH>Синтаксический анализатор.
Википедия говорит, что это синонимы...

A>>покрывающее, по крайней мере, строготипизированные языки программирования.

WH>Что такое строготипизированные языки программирования я так и не понял.
WH>Это слишком мутный термин.
А если убрать это слово, станет ли предложение верным?
Есть ли какие-нибудь органичения на то, какие языки можно выразить этим подходом?
Можно ли будет, например, сделать C++, OCaml, Scala, J и что-нибудь с зависимыми типами?

A>>Обычный подход — это для КЗ языка программирования выделить КС-ный надъязык, реализовать для него парсер с построением AST и следующим этапом уже вручную пройтись по полученному AST, достраивая "семантические" связи, расставляя типы и выявляя ошибки, которые не смог отловить парсер. Под "семантикой" тут подразумевается как раз та часть языка, которая не покрывается грамматикой используемого в данном конкретном случае КС-ного надъязыка.

WH>Использовать слово "семантика" в данном случае не верно.
WH>Ибо семантика языка задает смысл каждой строки языка.
"Смысл" — еще менее формализованное понятие. Имхо, все что сложнее терминалов — уже некоторым образом семантика. Например, идентификатор состоит из символов, т.е. семантикой этого набора символов является то, то он является идентификатором (более высокоуровневой конструкцией). Т.е. семантика — понятие относительное, в том смысле, что оно определяется относительно уровня абстракции, с которым мы в данный момент работаем. Все что ниже этого уровня можно обозначить как "дано", а выше — более высокоуровневые абстракции и связи между элементами нижнего уровня — семантика.
1. Лексеру (если он есть) на вход подаются символы, на выходе получаем токены — первый слой абстракции со своей семантикой.
2. Парсеру (если он КС) подаются токены, на выходе получаем AST — второй слой.
3. Далее рукопашный код, который сужает объем KC языка до спецификации целевого языка — третий слой со своими абстракциями (типами, перегрузками и т.п.)
4. Потом кодогенератор как отдельный слой...
Другое дело, что первые три слоя не всегда удачно разделяются (без хаков и прямых модификаций того, что приходит из нижних уровней). Если ты предлагаешь другую, более удачную декомпозицию на слои с инкапсуляцией рутинных вещей в красивый DLS — это очень интересно!

WH>Ибо семантика языка задает смысл каждой строки языка.

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

WH>А это все проверки на то принадлежит ли строка языку. Те синтаксис.

WH>Но Влад верит, что КС грамматика задает сам язык. То, что она задает не язык, а надмножество языка он не понимает.
Надмножество языка — тоже язык. Думаю, он просто опасается, что первые три уровня смешаются в одну большую кучу неподдерживаемого кода. Или что DSL для ее разруливания будет слишком сложным для простых смертных. Похожие мотивы и у тебя, когда ты борешься с распространенным пониманием термина "семантика" — чтобы никому даже в голову не приходило смешивать этот уровень с кодогенерацией, так?

Кстати, а нельзя ли саму кодогенерацию посадить на тот же движек? У макросов есть rewrite часть, которая трансформирует элемент более высокоуровневого языка в термины более низкоуровневого. А чем MSIL или машинный код не языки?! Если позволить макросу иметь несколько rewrite частей и выбирать нужную в зависимости от текущей платформы, текущего "базового" языка или какого-то промежуточного, то будем иметь дополнительную гибкость повторного использования кода. Нужно только как-то предотвратить перескакивание через языки — чтобы не позволить писать на Nemerle вперемежку с MSIL. Еще могут быть неоднозначности по какому пути идти от самого верхнего уровня к MSIL.
Re[14]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 27.06.11 13:45
Оценка:
Здравствуйте, Silver_S, Вы писали:

S_S>Какая разница как все называть, если реализация от этого не изменится.

Проблема в том что меняется.

S_S>Тогда получится что язык C# и его компилятор недетерминированны (или почти) — т.е. ошибка может выскочить а может и не выскочить, как повезет.

Я еще не видел ни одного языка синтаксис, которого был бы основан на генераторе случайных чисел.

S_S>Так это комиилятор C# синтаксическую ошибку, либо выдает либо не выдает(как повезет), или уже семантическую?

Семантических ошибок не бывает.
Ибо семантика задана для всех строк принадлежащих языку.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[14]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 27.06.11 13:45
Оценка:
Здравствуйте, artelk, Вы писали:

A>Википедия говорит, что это синонимы...

Мало ли что она говорит.

A>Есть ли какие-нибудь органичения на то, какие языки можно выразить этим подходом?

Думаю что любые.

A>Можно ли будет, например, сделать C++,

В первых версях нет. Ибо для С++ нужны дополнительные навороты (интеграция парсера с поиском имен), которые я буду делать потом.
Примеры ужоса:
a<b>c;
a*b;

Не заная что из себя представляют имена вменяемый АСТ не построить.

A>OCaml, Scala, J и что-нибудь с зависимыми типами?

Нивапрос.

A>"Смысл" — еще менее формализованное понятие. Имхо, все что сложнее терминалов — уже некоторым образом семантика.

Например в ПЕГе нет никаких терминалов. Так что вся твоя терминология строится на деталях реализации.
А должно быть наоборот.

A>1. Лексеру (если он есть) на вход подаются символы, на выходе получаем токены — первый слой абстракции со своей семантикой.

A>2. Парсеру (если он КС) подаются токены, на выходе получаем AST — второй слой.
A>3. Далее рукопашный код, который сужает объем KC языка до спецификации целевого языка — третий слой со своими абстракциями (типами, перегрузками и т.п.)
Вот это все синтаксический анализ.

A>Другое дело, что первые три слоя не всегда удачно разделяются (без хаков и прямых модификаций того, что приходит из нижних уровней).

А знаешь почему?
По тому, что это не три слоя, а один!

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

Это происходит на этапе кодогенерации. Те после того как синтаксический анализ завершён.

A>Надмножество языка — тоже язык.

Да. Но это другой язык.

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

Нет. Он просто не понимает, что если в языке есть требования "объявить перед использованием" то язык КЗ.
Доказано математически.

A>Или что DSL для ее разруливания будет слишком сложным для простых смертных. Похожие мотивы и у тебя, когда ты борешься с распространенным пониманием термина "семантика" — чтобы никому даже в голову не приходило смешивать этот уровень с кодогенерацией, так?

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

A>Кстати, а нельзя ли саму кодогенерацию посадить на тот же движек? У макросов есть rewrite часть, которая трансформирует элемент более высокоуровневого языка в термины более низкоуровневого. А чем MSIL или машинный код не языки?!

Правильно соображаешь.
Вот только Влад это не понимает.

A>Если позволить макросу иметь несколько rewrite частей и выбирать нужную в зависимости от текущей платформы, текущего "базового" языка или какого-то промежуточного, то будем иметь дополнительную гибкость повторного использования кода. Нужно только как-то предотвратить перескакивание через языки — чтобы не позволить писать на Nemerle вперемежку с MSIL. Еще могут быть неоднозначности по какому пути идти от самого верхнего уровня к MSIL.

Об этом я тоже думаю.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[15]: Размышления о типизаторе для Н2
От: artelk  
Дата: 27.06.11 15:46
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


A>>Википедия говорит, что это синонимы...

WH>Мало ли что она говорит.
Хорошо, а чем тогда они отличаются?

A>>Есть ли какие-нибудь органичения на то, какие языки можно выразить этим подходом?

WH>Думаю что любые.
Крута

A>>"Смысл" — еще менее формализованное понятие. Имхо, все что сложнее терминалов — уже некоторым образом семантика.

WH>Например в ПЕГе нет никаких терминалов. Так что вся твоя терминология строится на деталях реализации.
Вроде как есть.

A>>1. Лексеру (если он есть) на вход подаются символы, на выходе получаем токены — первый слой абстракции со своей семантикой.

A>>2. Парсеру (если он КС) подаются токены, на выходе получаем AST — второй слой.
A>>3. Далее рукопашный код, который сужает объем KC языка до спецификации целевого языка — третий слой со своими абстракциями (типами, перегрузками и т.п.)
WH>Вот это все синтаксический анализ.
Ок.

A>>Другое дело, что первые три слоя не всегда удачно разделяются (без хаков и прямых модификаций того, что приходит из нижних уровней).

WH>А знаешь почему?
WH>По тому, что это не три слоя, а один!
Строго-научно да. Но, с точки зрения практики, такое разбиение все равно целесообразно проводить и оно чаще всего приводило к заметному упрощению кода, не так ли? Хотя бы потому, что первые два слоя относительно легко посадить на геренатор парсера, а с третьим в этом смысле сложнее. Вот паттерны проектирования, например, далеко не точная наука. Однако это не значит, что реализацию не нужно разбивать на множество простых и слабосвязанных частей, если это не обоснованно строго-научно.

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

WH>Это происходит на этапе кодогенерации. Те после того как синтаксический анализ завершён.
Если язык удобно представить в виде "матрешки" (например: наднадъязык, надъязык и собственно язык), то семантика будет появляться при каждом переходе от внешнего языка к более детальному внутреннему, имхо.
Не понятно, почему ты считаешь кодогенерацию семантикой. Вроде это как раз тупое переписывание высокоуровневых элементов в другой, более низкоуровневый язык. Тут семантика как раз пропадает...
Или же оптимизация это семантика?

A>>Если позволить макросу иметь несколько rewrite частей и выбирать нужную в зависимости от текущей платформы, текущего "базового" языка или какого-то промежуточного, то будем иметь дополнительную гибкость повторного использования кода. Нужно только как-то предотвратить перескакивание через языки — чтобы не позволить писать на Nemerle вперемежку с MSIL. Еще могут быть неоднозначности по какому пути идти от самого верхнего уровня к MSIL.

WH>Об этом я тоже думаю.

Родилось такое:
syntax "if" of Nemerle
//многа ДСЛя
typing
//многа ДСЛя

//отдельно
rewrite "if" of Nemerle to Nemerle
{
  //тут только код на Nemerle и\или на языке, который в него транслируется
  match(...)
   ...
}

syntax "match" of Nemerle
//многа ядреного ДСЛя
typing
//многа ядреного ДСЛя

//отдельно
rewrite "match" of Nemerle to MSIL
{
  //тут только код на MSIL и\или на языке, который в него транслируется
}

//где-то совсем в другом месте - там, где требуется генерация в нэйтив
rewrite "match" of Nemerle to x86_assembler
{
  //тут только код на x86_assembler и\или на языке, который в него транслируется
}

Re[15]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.06.11 16:43
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Семантических ошибок не бывает.

WH>Ибо семантика задана для всех строк принадлежащих языку.

Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.06.11 16:49
Оценка:
Здравствуйте, artelk, Вы писали:

A>>>покрывающее, по крайней мере, строготипизированные языки программирования.

WH>>Что такое строготипизированные языки программирования я так и не понял.
WH>>Это слишком мутный термин.
A>А если убрать это слово, станет ли предложение верным?

Это у WolfHound-а стиль такой. Он вместо того чтобы просто что-то сказать выдает фантак сарказма.
В данном случае он имел в виду, что вместо "строготипизированные" нужно использовать термин "статическитипизированные".

А "строготипизированные" — это степень ревностности в отношении к проверкам типов. Строготипизированным может быть и скрипт. И термин действительно мутный.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.06.11 18:05
Оценка:
Здравствуйте, artelk, Вы писали:

A>3. Далее рукопашный код, который сужает объем KC языка до спецификации целевого языка — третий слой со своими абстракциями (типами, перегрузками и т.п.)


Вот здесь надо заменить "рукопашный код" на "генерируемый" и будет все пучочком.

A>4. Потом кодогенератор как отдельный слой...


Все давно украдено до нас (с).

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

A>Другое дело, что первые три слоя не всегда удачно разделяются (без хаков и прямых модификаций того, что приходит из нижних уровней). Если ты предлагаешь другую, более удачную декомпозицию на слои с инкапсуляцией рутинных вещей в красивый DLS — это очень интересно!


Они отлично разделяются. Если это не так — это беда конкретных реализаций.


WH>>Ибо семантика языка задает смысл каждой строки языка.

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

+1

WH>>А это все проверки на то принадлежит ли строка языку. Те синтаксис.

WH>>Но Влад верит, что КС грамматика задает сам язык. То, что она задает не язык, а надмножество языка он не понимает.
A>Надмножество языка — тоже язык. Думаю, он просто опасается, что первые три уровня смешаются в одну большую кучу неподдерживаемого кода. Или что DSL для ее разруливания будет слишком сложным для простых смертных.

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

Я практик и историю с над- и под-языками прошел на собственной шкуре. Даже при парсинге выгодно парсить более широкий язык, так как это позволяет добиться ряда преимуществ:
1. Выдавать пользователям более понятные и осмысленные диагностические сообщения. Иными словами, сделать компилятор/IDE более интеллектуальными.
2. Повторное использование и регулярность грамматики. Скажем в Немерле уточнение типов и задание типов у переменных (и т.п.) имеет одинаковый синтаксис — синтаксис бинарного оператора.

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

Одна беда — пользователю это не очень интересно. Ему хочется получить от компилятора максимально внятное объяснение в чем он не прав и подсказки говорящие как можно исправить ситуацию. Если это не обеспечить, то компиляторы (и тем более интелисенс в IDE) сделанные на основе этого инструмента будут практически никому не нужны.

Более того. Это еще и невозможно сделать. Парсинг останется парсингом, а типизация типизацией. При всех громких заявлениях WolfHound так и не продемонстрировал алгоритма разбора КЗ-грамматик, а умные люди давно посчитали, что это слишком вичислительно затратно. Так что на это надеяться нет смыла.

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

То что для некоторых языков (которые давно пора хоронить) при парсинге нужно использовать таблицу символов (аргумент WolfHound-а) ровным счетом ничего не значит. Если обратиться к столь нелюбимому WolfHound-ом Ахо, то на одной из первых картинок в его книге можно заметить диаграмму где слева находится таблица символов, а справа стадии анализа и генерации. Другими словами еще тыщы лет назад люди понимали, что таблица символов является аспектом проходящим на сквозь через все стадии компиляции. Ну, так и не фига ломать традиции без особых на то оснований?

A>Кстати, а нельзя ли саму кодогенерацию посадить на тот же движек?


Кодогенерация — это просто трансляция в другой язык. Автоматизировать этот просс нельзя, но придать ему декларативную форму вополне можно.

A>У макросов есть rewrite часть, которая трансформирует элемент более высокоуровневого языка в термины более низкоуровневого.


Это довольно тонкий вопрос.

Почему в низкоуровневый то? На самом деле макры транслируют все в тот же язык. Макры это не кодогенерация в том смысле в котором этот термин понимается в компиляторе.

Процесс раскрытия макросов — это рекурсивный процесс (или итеративный, если угодно). На некоторых итерациях на выходе макросов могут быть такие же высокоуровневые конструкции как и те что раскрываются. Далее они тоже будут раскрыты и так пока в коде не останется того что я называю базовым языком. А вот для него можно написать трансляцию в другой язык (который я называю TAST).

То есть в итоге код должен быть переписан в некий безмакроссный подязык (являющийся сабсэтом полного), но в процессе этого переписывания можно применять сколь-угодно высокоуровневые средства.

A>А чем MSIL или машинный код не языки?!


Отличный вопрос! Потому что MSIL — это другой язык. Трансляция в него и есть компиляция. Лепить трансляцию в MSIL на основании некого синтаксического сахара вроде foreach-а — это садомазохизм, так как это приведет к офигительному дублированию кода, серьезным сложностям и т.п. Скажем у linq-запросов из C# банально нет своей семантики. Она в спецификации выражается в терминах переписывания в другие конструкции C#. Лепить генерацию MSIL по linq-запросам — означает сдублировать кодогенерацию для вызова методов. А зачем это нужно?

A>Если позволить макросу иметь несколько rewrite частей и выбирать нужную в зависимости от текущей платформы, текущего "базового" языка или какого-то промежуточного, то будем иметь дополнительную гибкость повторного использования кода.


Это будет кабздец. Полный.

A> Нужно только как-то предотвратить перескакивание через языки — чтобы не позволить писать на Nemerle вперемежку с MSIL. Еще могут быть неоднозначности по какому пути идти от самого верхнего уровня к MSIL.


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

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

При таком подходе дальнеший процесс компиляции уже совершенно очевиден. Раз все что можно изобразить на макросах один фиг преобразуется в этот рассахаренный язык, то генерацию кода нужно делать только для этого под-языка. Типизация для него так же может быть описана декларативно. Единственное требование — для такого под-языка типизация должна быть задана обязательно (а вот для сахара она не обязательна, хотя и, зачастую, полезна).

Раз мы имеем фиксированный и типизированный АСТ (язык в объектной форме), то трансляция его в действительно более низкоуровневые язки становится совершенно примитивной задачей. Нужно просто задать таблицу соответствия.

Единственная проблема которая встает у нас на пути — не все платформы (здесь под платформами я понимаю .Net, Java и различные варианты нэтив-рантаймов) могут реализовывать примитивы которые поддерживаются нашим обессахаренным языком. Например, в платформах может не поддерживаться: замыканий, ФВП, классов и т.п. Это приводит к мысли о том, что требуются средства расщепления примитивов. По сути это тот же процесс раскрытия макросов, и наверное, его можно реализовать теми же средствами. Единственное отличие — раскрытие таких макросов будет происходить в зависимости от бэкэнда. Если бэкэнд поддрживает ту или иную сущность, то ему не нужно раскрывать этим макросы. В обратном случае он получит код на все том же под-языке, но без некоторых конструкции. Эти конструкции будут заменены на другие конструкции.

Например, не секрет, что замыкания можно выразить через классы, а классы через замыкания. Можно легко представить, что для некоторого гипотетического функционального рантайма придется устранить классы, переписав их в замыкания, а для дотнета с явой придется расщепить замыкания преобразовав их в классы, а возможно и просто переписав часть кода так, чтобы он стал императивным (т.е. произведя оптимизацию).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.06.11 18:44
Оценка:
Здравствуйте, artelk, Вы писали:

A>rewrite "if" of Nemerle to Nemerle

A>{
A> //тут только код на Nemerle и\или на языке, который в него транслируется
A> match(...)
A> ...
A>}

Вот это и есть макросы.

A>syntax "match" of Nemerle

A>//многа ядреного ДСЛя
A>typing
A>//многа ядреного ДСЛя

A>//отдельно

A>rewrite "match" of Nemerle to MSIL
A>{
A> //тут только код на MSIL и\или на языке, который в него транслируется
A>}

A>//где-то совсем в другом месте — там, где требуется генерация в нэйтив

A>rewrite "match" of Nemerle to x86_assembler
A>{
A> //тут только код на x86_assembler и\или на языке, который в него транслируется
A>}
A>[/code]
A>

А вот это уже есть задница, так как сгенерировать IL или asm по АСТ высокоуровневого языка (пуст даже типизированному) — это задача неберучка. В обоих кусках кода будет огромное дублирование кода.

Для справки. При компиляции match производится в несколько этапов:
1. Производится типизация паттерна. Тут в Н1 есть промашка этот этап слит со следующим.
2. Генерируется специализированное представление паттернов. В Н1 это представление выглядит так.
3. Далее происходит анализ специального представление и преобразование его в так называемое дерево вывода (decision tree).
4. Производится переписывание дерева вывода в код содержащий if-ы и goto. При этом части кода могут дублироваться, перемещаться и т.п.

Таким образом генерировать MSIL или asm по AST оператора match — это очень глупое занятие. Вместо этого имеет смысл иметь макрос-расщипитель (рассахариватель) заменяющий обращение к match на набор низкоуровневых конструкций. А кодогенерацию уже вести для них.

Более того! Код в который переписывается match — это уже не, например, Немерле! Ведь в Немерле нет goto и if (if макрос).

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

Итого можно вообразить следующую схему. У нас есть:
1. Макросы. Их цель — рассахаривание. Они переписывают язык X в него же самого. В конце раскрытия всех макросов мы должны получить рассахаренный язык X. Именно его я и называют базовым языком.
2. Кодогенераторы. Их цель — преобразовать над минимизированного языка X в язык Y. При этом в языке Y могут использоваться макросы.

В такой схеме бэкэнды становятся одним из типов кодогернераторов совмещенных с сериализацией в формат исполнимых файлов целевой платформы. Бэкэнд может использовать стандартные генераторы и раскрытие макросов с целью устранения из AST не поддерживаемых бэкэндом сущностей. Например, бэкэнд для дотнета устранит из AST замыкания, а бэкэнд для нэтив устранит вообще все кроме вызова функций и работы с переменными.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 27.06.11 19:12
Оценка:
Здравствуйте, artelk, Вы писали:

A>Строго-научно да. Но, с точки зрения практики, такое разбиение все равно целесообразно проводить и оно чаще всего приводило к заметному упрощению кода, не так ли? Хотя бы потому, что первые два слоя относительно легко посадить на геренатор парсера, а с третьим в этом смысле сложнее.

На самом деле и с первыми двумя все не просто.
Генераторы парсеров по EBNF особенно семейство LR страдают невнятными сообщениями об ошибках.

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

Паттерны проектирования это вообще зло.
Люди, начитавшись про паттерны, начинают лепить их куда попало.
Вообще самый правильный способ решать задачу это сначала сделать язык под задачу, а потом на этом языке ее решить.

A>Если язык удобно представить в виде "матрешки" (например: наднадъязык, надъязык и собственно язык), то семантика будет появляться при каждом переходе от внешнего языка к более детальному внутреннему, имхо.

Матрешка это деталь реализации.
Не более того.
И в твоем случае терминология начинает плавать в зависимости от деталей реализации.

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

Куда пропадает?

A>Или же оптимизация это семантика?

И она тоже.

A>Родилось такое:

Очень наивно.
На практике все будет весьма иначе.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[15]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 27.06.11 19:39
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Более того. Это еще и невозможно сделать. Парсинг останется парсингом, а типизация типизацией. При всех громких заявлениях WolfHound так и не продемонстрировал алгоритма разбора КЗ-грамматик, а умные люди давно посчитали, что это слишком вичислительно затратно. Так что на это надеяться нет смыла.

Пожалуйста цитату в студию где я обещал использовать КЗ грамматику.

VD>То что для некоторых языков (которые давно пора хоронить) при парсинге нужно использовать таблицу символов (аргумент WolfHound-а) ровным счетом ничего не значит.

Это просто констатация факта.

VD>Если обратиться к столь нелюбимому WolfHound-ом Ахо, то на одной из первых картинок в его книге можно заметить диаграмму где слева находится таблица символов, а справа стадии анализа и генерации. Другими словами еще тыщы лет назад люди понимали, что таблица символов является аспектом проходящим на сквозь через все стадии компиляции. Ну, так и не фига ломать традиции без особых на то оснований?

Я тебя что-то не понимаю.
То "пора хоронить" то "не фига ломать".

VD>Почему в низкоуровневый то?

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

VD>На самом деле макры транслируют все в тот же язык. Макры это не кодогенерация в том смысле в котором этот термин понимается в компиляторе.

Это именно что кодогенерация.

VD>Отличный вопрос! Потому что MSIL — это другой язык.

Немерле с if'ом и немерле без if'а это тоже разные языки.

VD>Трансляция в него и есть компиляция. Лепить трансляцию в MSIL на основании некого синтаксического сахара вроде foreach-а — это садомазохизм, так как это приведет к офигительному дублированию кода, серьезным сложностям и т.п.

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

VD>Скажем у linq-запросов из C# банально нет своей семантики. Она в спецификации выражается в терминах переписывания в другие конструкции C#. Лепить генерацию MSIL по linq-запросам — означает сдублировать кодогенерацию для вызова методов. А зачем это нужно?

Ты как ни крутись, а вызова по LINQ запросам тебе всеравно генерировать.

A>>Если позволить макросу иметь несколько rewrite частей и выбирать нужную в зависимости от текущей платформы, текущего "базового" языка или какого-то промежуточного, то будем иметь дополнительную гибкость повторного использования кода.

VD>Это будет кабздец. Полный.
Нет. Единственно верный путь.
Ты предлагаешь страшный костыль за те же деньги.

VD>Потому я в своих рассуждениях и ввел понятие базового языка. Базовый язык — это язык в который бессмысленно рассахаривать дальше. Он как безопасный ассемблер. Может все, но требует выписывания жудких деталей. Макросы же вводят в язык высокоуровневые конструкции которые могут быть переписаны в этот ассемблер.

Бла-бла-бла.
Базовый язык не существует.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[13]: Размышления о типизаторе для Н2
От: artelk  
Дата: 27.06.11 21:15
Оценка:
Здравствуйте, VladD2, Вы писали:

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


VD>На самом деле вся разница между нашими подходами заключается только в том допускается ли преобразование нетипизированного АСТ или нет.

На мой взгляд подход WH — это придумать механизм, в котором твой подход с базовым языком (и аналогичные ему) делаются наиболее просто, лаконично и в общем виде. Хотя как быть с linq — мне лично пока не понятно. С одной стороны, это как язык в языке со своей грамматикой, с другой — в нем позволяются вставки из внешнего языка. Как его типизировать, не типизируя эти вставки и вообще что будет его типом (догадываюсь, что не IEnumerable<T>), причем, чтобы это позволило использовать интеллисенс — не знаю. Жду, когда WH представит свой вариант.

VD>Базовый язык все равно будет. Вопрос только как его делать. Вручную или на базе все того же средства.

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

VD>Для проверки концепций достаточно создать маленький кусочек. Но чтобы его создать нужно сделать кучу побочной работы. Тот же "специализированный Меркури" включает в себя довольно много сложного кода большая часть которого есть в Н1. Это, в первую очередь, движок унификации который позволит унифицировать не просто термы (как в прологоподобных языках вроде Меркури), а типы с поддержкой подтипов. Это не маленький такой (и не самый простой) код. Только на его отдадку можно убить несколько месяцев. А на базе солвера из Н1 его можно создать очень быстро и просто. Он, конечно, будет далек от идеала по производительности, но для прототипа этого и не надо.

А не проще ли взять готовый Меркури и вызывать его в компайлтайме?
Re[17]: Размышления о типизаторе для Н2
От: artelk  
Дата: 27.06.11 21:38
Оценка:
Здравствуйте, VladD2, Вы писали:

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


VD>А вот это уже есть задница, так как сгенерировать IL или asm по АСТ высокоуровневого языка (пуст даже типизированному) — это задача неберучка. В обоих кусках кода будет огромное дублирование кода.

А я и не буду настаивать, чтобы match напрямую в IL или asm трансформировать. Согласен, между match и кодом целевой платформы нужно сделать еще несколько промежуточных языков. Т.е. транслировать только то, что транслируется просто, постепенно спускаясь на уровень платформы. При смене платформы достаточно создать алтернативные реализации только для достаточно низкоуровневых макросов, а всю сложную логику повторно использовать.

VD>Таким образом генерировать MSIL или asm по AST оператора match — это очень глупое занятие. Вместо этого имеет смысл иметь макрос-расщипитель (рассахариватель) заменяющий обращение к match на набор низкоуровневых конструкций. А кодогенерацию уже вести для них.

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

VD>Более того! Код в который переписывается match — это уже не, например, Немерле! Ведь в Немерле нет goto и if (if макрос).

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

VD>Итого можно вообразить следующую схему. У нас есть:

VD>1. Макросы. Их цель — рассахаривание. Они переписывают язык X в него же самого. В конце раскрытия всех макросов мы должны получить рассахаренный язык X. Именно его я и называют базовым языком.
Хмм.. рассахаренный match — это уже не Nemerle, т.е. не в него же самого.
VD>2. Кодогенераторы. Их цель — преобразовать над минимизированного языка X в язык Y. При этом в языке Y могут использоваться макросы.
А чем они принципиально отличаются от 1.?
Кстати, теоретически можно сделать компилятор IL в asm — свой ngen. Компиляция в IL будет кодогенератором или просто макросом?
Re[16]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.06.11 21:42
Оценка:
Здравствуйте, WolfHound, Вы писали:

VD>>Отличный вопрос! Потому что MSIL — это другой язык.

WH>Немерле с if'ом и немерле без if'а это тоже разные языки.

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

VD>>Трансляция в него и есть компиляция. Лепить трансляцию в MSIL на основании некого синтаксического сахара вроде foreach-а — это садомазохизм, так как это приведет к офигительному дублированию кода, серьезным сложностям и т.п.

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

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

Переписывание X в X делается тупым квази-цитированием. Переписывание, X в Y требует наличия кучи дополнительной информации (тех же типов и т.п.).

VD>>Скажем у linq-запросов из C# банально нет своей семантики. Она в спецификации выражается в терминах переписывания в другие конструкции C#. Лепить генерацию MSIL по linq-запросам — означает сдублировать кодогенерацию для вызова методов. А зачем это нужно?

WH>Ты как ни крутись, а вызова по LINQ запросам тебе всеравно генерировать.

И что? Мне их два раза сгенерировать? Один для псевдотипизации, а второй где будет типизироваться раскрытый код?

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


A>>>Если позволить макросу иметь несколько rewrite частей и выбирать нужную в зависимости от текущей платформы, текущего "базового" языка или какого-то промежуточного, то будем иметь дополнительную гибкость повторного использования кода.

VD>>Это будет кабздец. Полный.
WH>Нет. Единственно верный путь.
WH>Ты предлагаешь страшный костыль за те же деньги.

Я предлагаю отделить мух от котлет. Сначала раскрываем все макросы и производим типизацию. В итоге получаем код без макросов (только с АСТ для которого вычислены типы. Потом то что получилось преобразуем в другой язык. Это делаем спомощью максимально формализованного (формально описанного на неком ДСЛ-е) маппера. В этом другом языке так же могут быть макросы (а возможно типизация и другие прелести). Мы его так же раскрываем (рассахариваем). По получившемуся результату генерируем сборки для целевых платформ. Раскрытие макросов можно сделать условным. Это даст возможность бэкэнду не производить некоторых преобразований (если целевая платформа поддерживает фичу).

VD>>Потому я в своих рассуждениях и ввел понятие базового языка. Базовый язык — это язык в который бессмысленно рассахаривать дальше. Он как безопасный ассемблер. Может все, но требует выписывания жудких деталей. Макросы же вводят в язык высокоуровневые конструкции которые могут быть переписаны в этот ассемблер.

WH>Бла-бла-бла.

Снова хамишь.

WH>Базовый язык не существует.


Базовый язык — это язык в котором нечего раскрывать.

Совершенно по хрену когда происходит раскрытие макроса, до и или после типизации. Главное в макросе то, что он раскрывается в тот же язык (а значит может использовать все его примитивы). Преобразование же другой язык — это другое действие. При этом будет происходить изменение объектной модели.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 27.06.11 22:23
Оценка:
Здравствуйте, artelk, Вы писали:

A>На мой взгляд подход WH — это придумать механизм, в котором твой подход с базовым языком (и аналогичные ему) делаются наиболее просто, лаконично и в общем виде.

Ага. Но Влад это понять не может.
А самое смешное что мой подход как минимум не дороже того частного случая который хочет нахордкодить Влад.

A>Хотя как быть с linq — мне лично пока не понятно. С одной стороны, это как язык в языке со своей грамматикой, с другой — в нем позволяются вставки из внешнего языка. Как его типизировать, не типизируя эти вставки и вообще что будет его типом (догадываюсь, что не IEnumerable<T>), причем, чтобы это позволило использовать интеллисенс — не знаю. Жду, когда WH представит свой вариант.

При наличии модульного типизатора разници между linq и любой другой конструкцией языка не будет.

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

Этого он тоже не понимает.

A>А не проще ли взять готовый Меркури и вызывать его в компайлтайме?

Не проще.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[18]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.06.11 23:00
Оценка:
Здравствуйте, artelk, Вы писали:

VD>>Итого можно вообразить следующую схему. У нас есть:

VD>>1. Макросы. Их цель — рассахаривание. Они переписывают язык X в него же самого. В конце раскрытия всех макросов мы должны получить рассахаренный язык X. Именно его я и называют базовым языком.
A>Хмм.. рассахаренный match — это уже не Nemerle, т.е. не в него же самого.

В Nemerle оператор match является базовой конструкцией. Он не рассахиривается. Вот когда Nemerle конвертируется (отображается) в другой, более низкоуровневый язык, то match (в этом языке) уже будет макросом, и как следствие будет рассахариваться в конструкции if и goto.

Итого имеем стройную схему. Макросы рассахаривают язык в себя самого же (в том числе и с макросами), но в итоге макросы исчезают и остается одни базовые конструкции (те что не имеют тел). Вот они то и составляют базовый язык. Для таких макросов обязательна полная типизация (она не может быть опущена или задана частично).

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

Скорее всего процедура конвертации языков не будет такой же простой как макрос. Скорее всего там могут понадобиться нетривиальные преобразования. Например, несколько веток исходного языка в одну ветку целевого или наоборот. Так что скорее всего такой конвертер должен выглядеть как таблица отображения, а не как макрос. К тому же целевой язык не будет содержать правил грамматики (зачем они ему?).

VD>>2. Кодогенераторы. Их цель — преобразовать над минимизированного языка X в язык Y. При этом в языке Y могут использоваться макросы.

A>А чем они принципиально отличаются от 1.?

Моделью. Скажем исходный язык — это немерле. В нем есть match как базовое понятие и нет if и goto. Точнее if есть, но это макрос который является сахаром к match. Второй язык — это язык в котором нет match, точнее есть match, как макрос, и есть if и goto, как базовые конструкции. Кроме того целевой (2) язык не имеет таких штук как перегрузка и т.п. Он полностью определен и по нему можно генерировать код.

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

A>Кстати, теоретически можно сделать компилятор IL в asm — свой ngen.


В теории теория и практика эквивалентны, на практике — нет.

Это уже бессмысленные мечты. У ngen свои детали, которые делают этот продукт не простым. Вопросы парсинга и типизации при этом будет десятыми по важности. Да и нужды в этом нет. Никто не будет писать код на IL. Ну, а теоретически, да — можно.

A>Компиляция в IL будет кодогенератором или просто макросом?


Компиляция в IL — это вообще дело бэкэнда. Тут опят же важны детали. Кроме IL-а нужно еще ведь метаданные сборки сгенерировать.

Может ты ошибся и хотел сказать компиляция в асм (из IL-а)?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.06.11 23:05
Оценка:
Здравствуйте, artelk, Вы писали:

A>На мой взгляд подход WH — это придумать механизм, в котором твой подход с базовым языком (и аналогичные ему) делаются наиболее просто, лаконично и в общем виде.


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

Я же не против универсальных решений. Только в первую очередь решение должно быть удобным для конечного пользователя, делать то что нужно и быть понятным.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.06.11 23:24
Оценка:
Здравствуйте, WolfHound, Вы писали:

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

Как бы обобщить работу с типами, так чтобы с одной стороны не привязываться к ООП, а с другой иметь возможность не изобретать велосипед с тем же ООП (да еще и для каждого языка по новой)?

Вот это куда более интересно вопрос что называть языком или синтаксическим анализом.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[19]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 28.06.11 08:58
Оценка:
Здравствуйте, VladD2, Вы писали:

WH>>Это другой язык просто по определению.

WH>>Ибо он состоит из другого множества строк.
VD>
Знаю, знаю. Все лингвисты дебилы.

WH>>Повторной типизации не будет. Экспоненты тоже.

VD>
Ты как всегда лучше меня знаешь, как работают мои алгоритмы.

VD>Грубо говоря макрос переписывает код в тот же тип АСТ, а маппер отображает в другой.

А слабо формально?

WH>>Например, детерминированная финализация и полноценные продолжения существовать в рамках одного языка не могут.

VD>Это у тебя каша в голове.
Покажи, как ты собрался их совместить.

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

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

WH>>Про языки с другим вычислительным базисом и говорить нечего.

VD>Ну, вот и не будем.
И зря.

VD>

VD>Нет. Это у тебя каша в голове. Это чистый сахар.
Ну начнем с того что это другой язык по определению...

WH>>А PegGrammar?

VD>Нет.
Ох тыж блин. Это просто феерия.
Он имеет свою систему типов.
Свою вычислительную модель, не имеющую ничего общего с немерлом.
У него есть свои оптимизации, которые практически невозможно сделать, оставаясь в рамках немерла.
Он отличается от немерла сильнее, чем немерле от MSIL.
И после всего этого он не отдельный язык?
Что тогда можно назвать другим языком?
Формальное определение в студию.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[19]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 28.06.11 08:58
Оценка:
Здравствуйте, VladD2, Вы писали:

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

На который я уже дал ответ, но ты докопался до цвета пуговиц и даже не попытался понять суть.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[17]: Размышления о типизаторе для Н2
От: artelk  
Дата: 28.06.11 13:52
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


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

WH>Паттерны проектирования это вообще зло.
WH>Люди, начитавшись про паттерны, начинают лепить их куда попало.
Так это не сами паттерны виноваты, что кто-то, начитавшись их, лепит их куда попало, а то, что их представляют как панацею от всех бед и, вместо того чтобы думать своей головой, пытаются навтыкать их побольше в код.
Паттерны — это просто примеры довольно удачных часто встречающихся решений часто встречающихся проблем дизайна при разработке приложений на распространенных объектно-ориентированных языках программирования . С другой стороны, их можно рассматривать как примеры следования принципам SOLID. Изучать и анализировать их очень полезно. Еще хорошо то, что у них есть название и можно просто сказать, например, "тут нужен адаптер" вместо того, чтобы рассказывать 20 минут, что ты имеешь ввиду. Конечно, вопрос типа "какой бы мне тут паттерн применить, чтоб все стало хорошо" — глупость. Но если ты придумал удачное решение и обнаружил, что получился адаптер или еще что известное, то можно сразу использовать это название — другим будет нужно меньше объяснять что да как.
WH>Вообще самый правильный способ решать задачу это сначала сделать язык под задачу, а потом на этом языке ее решить.
На каждый чих делать DSL тоже не вариант. С другой стороны, дизайн классов — это тоже некоторым образом язык и если для какой-то задачи уже имеющихся языковых средств достаточно, чтобы выразить решение лаконично и понятно, то DSL клепать смысла нет.

A>>Если язык удобно представить в виде "матрешки" (например: наднадъязык, надъязык и собственно язык), то семантика будет появляться при каждом переходе от внешнего языка к более детальному внутреннему, имхо.

WH>Матрешка это деталь реализации.
WH>Не более того.
WH>И в твоем случае терминология начинает плавать в зависимости от деталей реализации.
Ага, понятия "больше" и "меньше" не строго-научны, т.к. один и тот же объект является большим по отношению к одним объектам и меньшим к другим — т.е. зависит от того, с чем мы его на практике сравниваем.

Кодогенерация тоже не так чтобы формализованная вещь. По сути это преобразование одного языка в другой. А "язык" — это очень растяжимое понятие.
Уже тут:
identifier : Identifier = !keyword "@"? identifierBody s;
identifier( _at             : NToken,
            identifierBody  : VString) : Identifier
{
  Identifier(identifierBody.Value)
}

чем не преобразование языков?

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

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

A>>Родилось такое:

WH>Очень наивно.
WH>На практике все будет весьма иначе.
Заинтриговал
Re[20]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.06.11 15:50
Оценка:
Здравствуйте, gbear, Вы писали:

VD>>>>Вот это грубейшая ошибка. Н без иф-а не перестает быть Н.

WH>>>Это у тебя каша в голове.
WH>>>Это другой язык просто по определению.
WH>>>Ибо он состоит из другого множества строк.
VD>>

G>Влад, а можно таки пояснить свои "смешки" для особо одаренных?


Это что-то вроде объяснения шутки. ОК, одаренность надо ценить.

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

G>"Не требуются новые понятия" значит. Они _[не]новые_ относительно чего?


Относительно имеющегося языка. Все тоже самое можно выразить на имеющемся языке, но (возможно) с большим объемом кода и не так удобно. Тут можно провести аналогию с естественными языками. От того что в язык вводится новое понятие язык не перестает быть языком. В то же время есть масса других языков требующих перевода перед прочтением.

G>Я правильно понимаю, что ты утверждаешь, что маппер это не "функция из АСТ в АСТ"?


Маппер — это функция отображения одного языка в другой. Именно это и является целью компиляции, по сути.

G>А можно и мне тоже так:


Валяй! Может созерцание своего "стиля" со стороны наведет WolfHound-а на мысль о том, что подобный стиль общения выглядит неприглядно.

G>Влад, на самом деле _любой_ синтаксический макрос — _формально_ — определяет новый язык.


На самом деле, конечно же — нет. Иначе тогда каждое новое понятие (термин) в естественном языке тоже порождало бы новый язык. Язык это нечто большее.

G>Пусть сколь угодно малый и простой. Пусть.


А кому нужно такое определение? Оно так же полезно как определение синтаксиса по WolfHound. То есть — никак.

G>Но, таки, _новый_ (т.е. _другой_) язык.


О! Супер! "Новый" и "другой" у нас уже разные вещи.

G>Выражений этого языка — их просто не существует в исходном. Вот и всё.


Вот у нас есть термин "программирование". Когда-то этого термина в языке не было. Какое-то время люди использовали фразу вроде "процесс создания компьютерных программ". Потом им это надоело и они ввели термин "программирование". Ну, и что? У нас появился новый русский язык? Однозначно — нет. Мы получили другой язык? Право смешно. Ну, так а почему макросы, переписываемые в терминах исходного языка, должны порождать новый язык?

G>А то, что выражения этого языка (определенного синтаксическим макросом) отображаются в выражения исходного языка — того, для которого этот "макрос" создан — абсолютно ничего не меняет.


Это для трепачей-теоретиков ничего не меняет. Хотя даже теоретику ясно, что трансформация одного языка в другой язык и замена терминов на их определения — это разные вещи.

На практике же разница очень значительна. Если не вводятся новые базовые возможности, то переписывание является простым и безопасным процессом, который можно доверить относительно неопытному программисту (прикладнику). При такой трансформации в результирующем коде могут появляться любые конструкции этого же языка (в том числе и та что раскрывается).

При преобразовании в другой язык, напротив, в результате должна появиться иерархия другого языка. В этой иерархии не должно быть вхождений исходного языка. Из этого следует, что трансформация "язык -> язык" должна быть пакетной операцией. Кроме того, так как при подобных трансформациях мы имеем дело не с синтаксическим сахаром, может случиться так (и обязательно случится), что невозможно будет заменить одну ветку исходного языка на одну или более целевого (что нормально для макросов). Обязательно будут случаи когда нужно преобразовывать набор ветвей исходного языка. И тут подход макросов попросту не подойдет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[20]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.06.11 15:59
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Что тогда можно назвать другим языком?

WH>Формальное определение в студию.

Язык который нельзя выразить в терминах исходного языка. Все остальное — синтаксические расширения.

Например, MSIL или asm явно другой язык по сравнению с Nemerle, так как в Nemerle нет таких понятий как стек, безусловные переходы и т.п.

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

Саму грамматику можно рассматривать как "другой язык". Но в этом нет особого смысла и это явно приведет к проблемам (совмещать другой язык и части исходного будет трудно).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[20]: Размышления о типизаторе для Н2
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.06.11 17:12
Оценка:
Здравствуйте, WolfHound, Вы писали:

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

WH>На который я уже дал ответ, но ты докопался до цвета пуговиц и даже не попытался понять суть.

Очень в твоем стиле. Бессмысленно и не конструктивно.

Если ты чего-то говорил, то дай ссылку. Ты так много говоришь, что не трудно и пропустить интересную мысль.

Лично для меня этот вопрос не праздный. По поводу управления типами у меня пока что четкого представления не сформировалось.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[21]: Размышления о типизаторе для Н2
От: gbear Россия  
Дата: 29.06.11 03:43
Оценка:
Здравствуйте, VladD2, Вы писали:

G>>"Не требуются новые понятия" значит. Они _[не]новые_ относительно чего?

VD>Относительно имеющегося языка. Все тоже самое можно выразить на имеющемся языке, но (возможно) с большим объемом кода и не так удобно. Тут можно провести аналогию с естественными языками. От того что в язык вводится новое понятие язык не перестает быть языком. В то же время есть масса других языков требующих перевода перед прочтением.

Замечательно. Только вот если таки проводить аналогию с естественными языками, синтаксический макрос не вводит, как ты выражаешься, "новое понятие". Отнюдь. Но он вводит новые языковые конструкции — новые _выражения_. Т.е. синтаксический макрос, в рамках предлагаемой тобой аналогии, это — эдакий "_жаргон_". Это достаточно грубо с формальной т.з., но все же ближе к реальности, чем то, что предлагаешь ты. Просто, не стоит забывать что синтаксический макрос, в отличие от, вносит в исходный язык и новую _грамматику_.

И опять же, тот факт что выражения "жаргона" можно выразить на исходном языке, ничего не меняет. В естественных языках жаргоны (и т.п. вещи) не рассматриваются как отдельные _языки_ по одной простой причине. Они не имеют собственной грамматической системы, заимствуя её от исходного языка. Синтаксические макросы — имеют свою грамматику.

G>>Пусть сколь угодно малый и простой. Пусть.

VD>А кому нужно такое определение? Оно так же полезно как определение синтаксиса по WolfHound. То есть — никак.

Какое "такое"?! Я не давал никаких _новых_ определений. Просто для меня очевидно, что синтаксический макрос, с т.з. ТФЯ — определяет _язык_. Язык — ровно в том же смысле, в котором, например, Nemerle — это _язык_.

G>>Но, таки, _новый_ (т.е. _другой_) язык.

VD>О! Супер! "Новый" и "другой" у нас уже разные вещи.

Извини, Влад, но "новый" и "другой" это таки действительно разные вещи. Я использовал "новый", и пояснил, что "новый" — в смысле "другой"... не такой как исходный. А не, например, "новый" вообще... такой, которого до этого еще не было.

G>>Выражений этого языка — их просто не существует в исходном. Вот и всё.

VD>Вот у нас есть термин "программирование". Когда-то этого термина в языке не было. Какое-то время люди использовали фразу вроде "процесс создания компьютерных программ". Потом им это надоело и они ввели термин "программирование". Ну, и что? У нас появился новый русский язык? Однозначно — нет. Мы получили другой язык? Право смешно. Ну, так а почему макросы, переписываемые в терминах исходного языка, должны порождать новый язык?

Влад, _термин_ и _выражение_ это все таки тоже _разные_ вещи. Ведь так?

G>>А то, что выражения этого языка (определенного синтаксическим макросом) отображаются в выражения исходного языка — того, для которого этот "макрос" создан — абсолютно ничего не меняет.

VD>Это для трепачей-теоретиков ничего не меняет. Хотя даже теоретику ясно, что трансформация одного языка в другой язык и замена терминов на их определения — это разные вещи.

Послушай. Все очень просто. Т.к. синтаксический макрос (любой) таки определяет _язык_ (пусть и сколь угодно простой), то, как таковой, замены "терминов на их определения" — просто не существует. Просто в некоторых случаях (и, если ты будешь утверждать, что в _большинстве_ случаев — я соглашусь с тобой) специально представлять выражения вводимые языком такого макроса в виде отдельного АСТ, и только потом выполнять трансформацию "одного языка в другой язык" — сильно избыточно. В этих случаях, АСТ "константное", и этапом его построения можно пренебречь. Всё что остается — это описать ф-цию преобразования АСТ выражений такого макроса в АСТ выражений исходного языка. Причем, такая ф-ция будет написана с учетом того, что АСТ выражений макроса у нас _всегда_ "такое". Это сделать легко, когда мощность множества выражений задающихся таким макросом мала. Только и всего.

Как только мощность выражений такого макроса начнет расти, такой способ станет не удобным. Это примерно как... ну вот до какого-то уровня сложности языка, можно (и даже наверное удобнее) работать с ним на уровне "сырого" текста. Но ты же не будешь спорить с тем, что, вообще говоря, "правильно" работать на уровне АСТ?


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


Извини, но с моей т.з., разница совсем не в этом. Я её попытался объяснить тебе чуть выше.

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


Погодь! Вот это: "должна появиться иерархия другого языка" что означает? Если можно, "на пальцах".

VD>Кроме того, так как при подобных трансформациях мы имеем дело не с синтаксическим сахаром, может случиться так (и обязательно случится), что невозможно будет заменить одну ветку исходного языка на одну или более целевого (что нормально для макросов). Обязательно будут случаи когда нужно преобразовывать набор ветвей исходного языка. И тут подход макросов попросту не подойдет.


Влад, ну вот просто попробуй представить, что ну хоть тот же макрос forech — задает таки _язык_. Да, этот язык будет весьма примитивный. Но это же не означает, что выражения этого языка нельзя представить в виде отдельного АСТ! Другое дело, что для этого конкретного языка это, наверное, имеет мало смысла. Но таки можно. И если я тебя правильно понял, то даже в этом случае у нас будет именно "набор ветвей". Ведь так?

Или что ты понимаешь под "набором ветвей"?
Re[21]: Размышления о типизаторе для Н2
От: gbear Россия  
Дата: 29.06.11 04:51
Оценка:
Здравствуйте, VladD2, Вы писали:

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


WH>>Что тогда можно назвать другим языком?

WH>>Формальное определение в студию.

VD>Язык который нельзя выразить в терминах исходного языка. Все остальное — синтаксические расширения.

VD>Например, MSIL или asm явно другой язык по сравнению с Nemerle, так как в Nemerle нет таких понятий как стек, безусловные переходы и т.п.

Если расширять твою аналогию с естественными языками, то, то, что ты описал выше — это всего лишь лексическая лакунарность. Различать языки по наличию/отсутствию лакунарности — глупо.
Вот ты говоришь: "MSIL или asm явно другой язык по сравнению с Nemerle" — и с этим трудно не согласиться. Но означает ли это, что с твоей точки зрения MSIL и asm это один и тот же язык?

VD>Одно из важных требований "другого языка" — он не может использовать терминов из исходного. А вот PegGrammar этим занимается. Он наполовину его обработчики, сам класс) — это намерл.


Вообще "терминов из исходного"? Или _только_ "терминов из исходного"? А то ведь некоторые "термины" они... скажем так, получили очень уж широкое распространение

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

А вот по моему глубокому мнению, как раз разница _грамматик_, в первую очередь, и указывает на разницу языков. И мне совершенно не понятны к каким таким особенным "проблемам" при "совмещении" это приведет. Как раз наоборот. Мухи будут отдельно, а котлеты — отдельно.

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

Другая, уже упомянутая выше, проблема — лексическая лакунарность. В рамках формальных языков решается ровно точно так же как и в естественных. То что в языке нет какого-либо "термина", совсем не означает, что этот "термин" не возможно на этом языке описать.

P.S. Про языки с разным "вычислительным базисом", тут вроде как договорились не говорить.
Re[22]: Размышления о типизаторе для Н2
От: WolfHound  
Дата: 29.06.11 09:32
Оценка:
Здравствуйте, gbear, Вы писали:

G>P.S. Про языки с разным "вычислительным базисом", тут вроде как договорились не говорить.

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