Именованные туплы и более типизированные массивы
От: hi_octane Беларусь  
Дата: 14.02.11 14:32
Оценка: 20 (2) +1
Для хардкорной математики очень нужны странные фичи

1. Именованные туплы, а лучше именование параметров Generic'ов:

func() : (a:int * b:int * color:int)
{
  def x = new { a = 5, b = 20, color=30 };//тут по пальцам если вместо a и b указаны x и y, идеально если ещё и порядок не важен
  x;
}

//использование
def r = func();

Console.WriteLine(r.a);
Console.WriteLine(r.b);
Console.WriteLine(r.color);

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

2. Сильная типизация алиасов, с типизацией индексов массивов:
type Idx = int;
type Idy = int;
type Idz = int;

//объявление двумерного ступенчатого массива, с индексаторами Idx, Idy и типом значения Idz
def a : array[(dimension1 : Idx) array[(dimension2 : Idy) Idz]];

//тут компилятор даст по пальцам, т.к. у массива типы не int
a[5][10] = 20; 
//тут ок, т.к. у массива индексаторы правильных типов, и значение тоже правильного типа
a[5:Idx][10:Idy] = 20:Idz;

def iX = 1 : Idx;
def iY = 2 : Idy;
//с этого момента iX и iY - самостоятельные типы, 
//которые к int приводятся только через операторы : и :>
//соответственно встроенные операторы сложения вычитания и т.п. 
//тоже начинают понимать только значения правильного типа

Console.WriteLine(a[iX][iX]);//ошибка компиляции, второй индекс должен быть типа Idx;
Console.WriteLine(a[iX][iY]);//всё ок

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

Интересует, в каком направлении копать, и насколько сложно эти две задачи реализовать в Н1 (пусть даже ценой поддержания собственной версии компилятора, если больше никому не надо). И огромная просьба учесть нужность этих фич для системы типов Н2.
Также буду благодарен за критику и возможные идеи в данных направлениях.
фича математика именованные туплы сильные алиасы feature math named tuples strong type aliases
Re[2]: Именованные туплы и более типизированные массивы
От: hi_octane Беларусь  
Дата: 06.03.11 20:45
Оценка: 7 (1)
__>А как это должно работать ?
__>Т.е. что вы хотите конкретно получить ? Возможно это не получится сделать.

Сначала что я хочу получить. Прежде всего хочу получить мало ошибок на очень сложных алгоритмах — неслучайно я написал про хардкорную математику. В следующем проекте у нас весьма много задач числодробильных, с очень многомерными массивами. Очень — т.е. 5-7 измерений это обычное дело, а вообще до наверное 20 будет доходить в некоторых алгоритмах. Получается что на ловлю блох с индексами массивов будет уходить хорошо если месяц из года работы одного математика. Т.е. затраты очень велики, и с ростом сложности алгоритмов будут расти нелинейно. В тоже время компилятор вполне спокойно мог бы проверять за нас типы индексов массивов, точно также как сейчас он это делает для индексаторов объявленных в своих классах. Для этого нужно собственно 2 фичи — 1) возможность задать сам "strong type", и возможность каким-то образом описать что какой-то массив, класс, структура или метод должен принимать эти "strong type" в каких-то местах.

Если обе эти задачи обобщить — то получается что и "strong type" и "массив индексируемый strong type" — это почти одно и тоже. Для реализации нужна возможность введения "макротипов", которые бы существовали только на этапе компиляции, и на этапе компиляции вели бы себя совсем как настоящие типы. Компилятор по идее работал бы с ними на всех этапах как с обычными типами, выводил, проверял, конвертировал и т.п.
Но в последний момент, перед самой генерацией IL вместо себя они должны подставлять реальные типы или даже генерировать код который нужно подставлять вместо обращения например к своим полям или к несуществующим методам, переписывать операторы приведения каким-то образом, и т.п.

Чувствую что у этой фишки могло бы быть куда больше применений, чем один лишь контроль индексаторов, например на них можно сделать своё именование параметров Generic классов, полученных даже из BCL:

def d : Dictionary[ItemDatabaseCode : int, ItemName : string] = Dictionary();


в этот момент создаётся такой виртуальный strong type для Dictionary, и далее в автокомплите, в функциях которые принимают этот Dictionary, в общем везде, мы получаем подсказу что первый параметр это ItemDatabaseCode, второй ItemName.

А после того как класс скомпилировался, компилятор везде подставляет обычный Dictionary из BCL. Ну и в идеале на него можно навесить аттрибуты, указывающие что TKey в миру ItemDatabaseCode, а TValue это ItemName, и корректно подхватить такое именование даже между проектами. При интероперабельности с C# там будет обычный Dictionary из BCL, с убогими подсказами что TKey это int, TValue string, и пара ненужных аттрибутов.

Ну и понятно люди найдут очень много применений которых я даже не представляю. Возможно это всё вообще можно будет в пределе довести до эдакого "семантического контроля над размерностями" в рамках целого солюшена, исключая целые классы ошибок вроде перепутывания каких-нить id-шек из базы, циклов по "не тем" коллекциям, и т.п.
Re[6]: Именованные туплы и более типизированные массивы
От: Аноним  
Дата: 14.02.11 18:07
Оценка: :)
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, <Аноним>, Вы писали:


А>>Разве механизм вывода типов не сделает типы эквивалентными в примере ТС.

WH>Если он будет знать про "сильные алиасы" то конечно нет.

а разве в немерли есть сильные алиасы?
Re[2]: Именованные туплы и более типизированные массивы
От: hi_octane Беларусь  
Дата: 14.02.11 19:49
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

_>>И огромная просьба учесть нужность этих фич для системы типов Н2.

WH>У меня есть кое какие мысли по расширяемой системе типов чтобы можно было делать произвольные статически типизированные ДСЛ.
Так ты прежде чем делать, какой диз-док опубликуй, ибо необходимость расширять типы есть, причём расширять даже в тех местах где .NET вроде как не позволяет (тот же мой пример с типизацией Array). А как правильно сделать — можно придумать только рассмотрев как можно больше сценариев использования. Например мне в проекте ещё нужны виртуальные наследники, которые существуют только в уме у компилятора, а в IL от них остаются только базовые классы. Ту же типизацию индексаторов можно было бы сделать создав виртуального наследника от массива, у которого индексаторы были бы типизированы, но на последнем этапе компиляции подменялись бы на реальные типы.

WH>Скажем тот же ПЕГ парсер был бы проще и лучше бы интегрировался с ИДЕ если бы я мог расширить систему типов так чтобы немерле смог выводить типы для правил.

WH>Также можно будет сделать dynamic из C# просто расширением системы типов.
dynamic малость ущербен — у него не может быть интеллисенса и compile-time валидации. Более правильно было бы сделать dynamic псевдо-типизируемым дженериком. Например:
def d = obj : dynamic<IList>;
d.|/* <- тут автокомплит показывает методы и свойства IList, 
есть проверка синтаксиса, аргументов, и т.п. При этом компилятор ругается на попытки 
сделать что-то за пределами IList. Но это не кастинг, вызовы идут обычным 
механизмом динамиков, т.е. obj вполне может от всего IList поддерживать только Count.*/

Это кстати тоже кусочек системы типов. Когда тип виртуально есть, а реально вместо него object запечёный с сахаром.

WH>Там есть еще куча всего что я хочу сделать.

WH>Это касается как функциональности так и оптимизаций (я знаю как сделать его еще быстрее ).
Имхо логично сделать сначала медленный парсер, но чтоб его начали прикручивать к Н2 пораньше, а ускорять уже в процессе. Но, полагаю, ты это и без меня прекрасно знаешь
Re[3]: Именованные туплы и более типизированные массивы
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.03.11 08:11
Оценка: +1
Здравствуйте, hi_octane, Вы писали:

WH>>Там есть еще куча всего что я хочу сделать.

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

Парадоксально то, что парсер УЖЕ БЫСТРЫЙ. Но мы уже две недели сидим и ждем нужных нам фич и не можем продолжать работу над парсером Н2.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Именованные туплы и более типизированные массивы
От: Аноним  
Дата: 14.02.11 14:54
Оценка:
Здравствуйте, hi_octane, Вы писали:

Крайне заинтересовало чем именно занимаетесь. Есть возможно схожие интересы.

1. Думаю проблем сделать не будет.

2. Не думаю что будет сделать просто.
Re: Именованные туплы и более типизированные массивы
От: WolfHound  
Дата: 14.02.11 16:49
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>И огромная просьба учесть нужность этих фич для системы типов Н2.

У меня есть кое какие мысли по расширяемой системе типов чтобы можно было делать произвольные статически типизированные ДСЛ.
Скажем тот же ПЕГ парсер был бы проще и лучше бы интегрировался с ИДЕ если бы я мог расширить систему типов так чтобы немерле смог выводить типы для правил.
Также можно будет сделать dynamic из C# просто расширением системы типов.
Но пока я разбираюсь с парсером.
Там есть еще куча всего что я хочу сделать.
Это касается как функциональности так и оптимизаций (я знаю как сделать его еще быстрее ).
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Именованные туплы и более типизированные массивы
От: Аноним  
Дата: 14.02.11 16:55
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


_>>И огромная просьба учесть нужность этих фич для системы типов Н2.

WH>У меня есть кое какие мысли по расширяемой системе типов чтобы можно было делать произвольные статически типизированные ДСЛ.
WH>Скажем тот же ПЕГ парсер был бы проще и лучше бы интегрировался с ИДЕ если бы я мог расширить систему типов так чтобы немерле смог выводить типы для правил.
WH>Также можно будет сделать dynamic из C# просто расширением системы типов.
WH>Но пока я разбираюсь с парсером.
WH>Там есть еще куча всего что я хочу сделать.
WH>Это касается как функциональности так и оптимизаций (я знаю как сделать его еще быстрее ).

Разве вывод типов не сделает их эквивалентными?
Re[3]: Именованные туплы и более типизированные массивы
От: WolfHound  
Дата: 14.02.11 17:01
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Разве вывод типов не сделает их эквивалентными?

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

WH>Здравствуйте, <Аноним>, Вы писали:


А>>Разве вывод типов не сделает их эквивалентными?

WH>Не понял вопрос.

Разве механизм вывода типов не сделает типы эквивалентными в примере ТС.
Re[5]: Именованные туплы и более типизированные массивы
От: WolfHound  
Дата: 14.02.11 17:11
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Разве механизм вывода типов не сделает типы эквивалентными в примере ТС.

Если он будет знать про "сильные алиасы" то конечно нет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Именованные туплы и более типизированные массивы
От: WolfHound  
Дата: 14.02.11 20:26
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>Так ты прежде чем делать, какой диз-док опубликуй, ибо необходимость расширять типы есть, причём расширять даже в тех местах где .NET вроде как не позволяет (тот же мой пример с типизацией Array).

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

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

Ну я так и делаю.
Правда он у меня уже очень даже не медленный. А будет еще быстрее.
Одна из мыслей дать пользователю возможность давать компилятору хинты на тему какие символы в данном месте всречаются чаще.
Например этот код генерирует ужасающее колличество проверок:
      letterCharacter       = [Lu, Ll, Lt, Lm, Lo, Nl];
      combiningCharacter    = [Mn, Mc];
      decimalDigitCharacter = [Nd];
      connectingCharacter   = [Pc];
      formattingCharacter   = [Cf];

      identifierStartCharacter  = letterCharacter / "_";
      identifierPartCharacters  = letterCharacter / decimalDigitCharacter / connectingCharacter / combiningCharacter / formattingCharacter;
      identifierBody            = identifierStartCharacter identifierPartCharacters*;

Хоть я и сделел генерацию бинарного поиска но всеравно много. Плюс код толстый -> промахи кеша.
При этом в подавляющем большенстве случаев этот код не встретит ничего кроме латинских букв, цифр и "_".
И если правило переписать так:
      identifierStartCharacter  = [hint: 'a'..'z' + 'A'..'Z' + '_'] (letterCharacter / "_");
      identifierPartCharacters  = [hint: 'a'..'z' + 'A'..'Z' + '_' + '0'..'9'] (letterCharacter / decimalDigitCharacter / connectingCharacter / combiningCharacter / formattingCharacter);

и проверять сначала то что попадает в диапозон заданный хинтом то можно сэкономить много проверок в наиболее частых случаях.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Именованные туплы и более типизированные массивы
От: _nn_ www.nemerleweb.com
Дата: 14.02.11 21:29
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>Для хардкорной математики очень нужны странные фичи


_>1. Именованные туплы, а лучше именование параметров Generic'ов:


_>
_>func() : (a:int * b:int * color:int)
_>{
_>  def x = new { a = 5, b = 20, color=30 };//тут по пальцам если вместо a и b указаны x и y, идеально если ещё и порядок не важен
_>  x;
_>}

_>//использование
_>def r = func();

_>Console.WriteLine(r.a);
_>Console.WriteLine(r.b);
_>Console.WriteLine(r.color);
_>

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

[Record]
class R
{
  public A     : int { get; }
  public B     : int { get; }
  public Color : int { get; }
}

def f() : R
{
  def x = R(a = 5, b = 20, color = 30);
  x
}


Чем такой вариант не устраивает ?
Как вариант можно еще укоротить макросом скажем наподобие:

[assembly: DefineRecord(A : int, B : int, Color : int)]


А если значение функции используется локально, то проще тогда уже просто тупл вернуть

def func() { (1,2,3) }

def (a, b, color) = func;
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Именованные туплы и более типизированные массивы
От: hi_octane Беларусь  
Дата: 14.02.11 22:08
Оценка:
Здравствуйте, _nn_, Вы писали:

__>
__>def f() : R
__>{
__>  def x = R(a = 5, b = 20, color = 30);
__>  x
__>}
__>


__>Чем такой вариант не устраивает?

Математики от меня наглядности требуют. В случае если таких методов штук 20 наберётся — получится столько-же Record'ов, и все с одной лишь целью — вернуть значение или список значений. Наглядность за этим R для них теряется. Тупл тоже отклоняют — завязываться на порядок аргументов или возвращаемых значений для них смерти подобно.

Про варианты объявления Record'а макросом я много думал, и пробовал. Думал также расширить макрос IAnonymous, таким образом чтобы он возвращал наследника от IAnonymous, с объявленными пропертями. Но нужно максимально информативное и объявление функции и использование её результата. Основная проблема, судя по всему, в объявлении, где нужно смешать и имена и типы, а имён в типе возвращаемого значения сейчас никто не ждёт. Вот это и хочется победить. Record был бы идеален, если бы объявлялся непосредственно как возвращаемое значение функции.

В общем основной вопрос, действительно ли сложно допилить компилятор таким образом, чтобы при разборе туплов расширенная информация о типах и именах скармливалась в какой-то макрос, который бы это разбирал, создавал нужный рекорд на уровне сборке, и далее по образу и подобию IAnonymous. Пока эта задача не выглядит простой, но я очень давно в компилятор не заглядывал, вот и хочу получить напутствие... может там на 3 человеко-месяца рефакторинг, и лучше эти силы вложить в помощь в разработке этих же фич но для Н2.
Re: Именованные туплы и более типизированные массивы
От: Ziaw Россия  
Дата: 15.02.11 15:21
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>Для хардкорной математики очень нужны странные фичи


_>1. Именованные туплы, а лучше именование параметров Generic'ов:


_>
_>func() : (a:int * b:int * color:int)
_>{
_>  def x = new { a = 5, b = 20, color=30 };//тут по пальцам если вместо a и b указаны x и y, идеально если ещё и порядок не важен
_>  x; // по пальцам будет тут конечно
_>}
_>

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

Фича отличная, нужна. Вообще нужен эффективный duck typing, с ним это реализуется легко.

_>2. Сильная типизация алиасов, с типизацией индексов массивов:

_>
_>type Idx = int;
_>type Idy = int;
_>type Idz = int;

_>//объявление двумерного ступенчатого массива, с индексаторами Idx, Idy и типом значения Idz
_>def a : array[(dimension1 : Idx) array[(dimension2 : Idy) Idz]];
_>


Фича спорная, до ума ее довести довольно сложно.
Re[3]: Именованные туплы и более типизированные массивы
От: _nn_ www.nemerleweb.com
Дата: 06.03.11 08:23
Оценка:
Здравствуйте, hi_octane, Вы писали:

<skip>

Я полагаю , что это как раз можно сделать с метаатрибутом.
Знающие люди подскажут насколько такое реально сделать.

Что-то в стиле:
[CreateType(FRet, a : int, b : int)]
public F() : FRet
{
  def x = FRet(a = 1, b = 2);
  x
}


Где CreateType создает тип в классе по аргументам.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Именованные туплы и более типизированные массивы
От: BogdanMart Украина  
Дата: 06.03.11 10:54
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>//тут компилятор даст по пальцам, т.к. у массива типы не int
_>a[5][10] = 20; 
_>//тут ок, т.к. у массива индексаторы правильных типов, и значение тоже правильного типа
_>a[5:Idx][10:Idy] = 20:Idz;


можно зделать так:

enum Idx : int {}

class MyList[Tindex,Tval]
where Tindex : int
{
_l : List[Tval] = List();

public Item[index : Tindex] : Tval // опускаю все методы кроме индексатора
{ // потому что пример чисто
get
{
_l[index]
}
set
{
_l[index] = value;
}
}
}
и использование:
      def l = MyList.[int,int]();
      l[0] = 5;
      
      def l = MyList.[Idx,int](); // Тут почему то дает ошибку: Error: expected int+, got Nemrrrr.Idx in generic specifier: Nemrrrr.Idx is not a subtype of System.Int32 [simple require]
      l[0 :> Idx] = 5;   // если  убрать where Tindex : int  то эта строчка работает


Думаю если пофиксить выведение типов для структур то это будет вполне реализуемо!
Re[2]: Именованные туплы и более типизированные массивы
От: BogdanMart Украина  
Дата: 06.03.11 10:56
Оценка:
Извиняюсь за битый листинг:
  enum Idx : int {}
  
  class MyList[Tindex,Tval]
    where Tindex : int
  {
    _l : List[Tval] = List();
    
    public Item[index : Tindex] : Tval
    {
      get
      {
        _l[index]
      }
      set
      {
        _l[index] = value;
      }
    }    
  }
Re[4]: Именованные туплы и более типизированные массивы
От: hi_octane Беларусь  
Дата: 06.03.11 11:10
Оценка:
__>Я полагаю , что это как раз можно сделать с метаатрибутом.
__>Знающие люди подскажут насколько такое реально сделать.

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

[ExpandToRecord]
Func(a : int, b : bool, out c : int, out m : decimal) : void
{
//здесь компилятор искаропки проследит чтобы возвращаемые значения были правильно заданы, и т.п.
}

//а аттрибут создаёт пару типов AB и CM, и различные версии функции, которые вызывают основную
Func(ab : AB) : CM
{  
  def cm = CM();
  Func(ab.a, ab.b, out cm.c, out cm.m);
  cm;
}

Func(ab : AB, out c : int, out m : decimal) : void
{ 
}

Func(a : int, b : bool) : CM
{
}


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

Но вот как быть с типизированными индексами массивов пока не знаю Частную задачу из одних массивов решать не хочется. Круто было бы если бы удалось совместно с кем-то продумать и ввести в язык "макротипы", которые ведут себя совсем как настоящие, но на какой-то из последних стадий разворачиваются в то, во что сами решат. Но тут нужно тотальную ревизию понятия "тип" проводить, и не факт что я с этим справлюсь.
Re[5]: Именованные туплы и более типизированные массивы
От: BogdanMart Украина  
Дата: 06.03.11 11:18
Оценка:
Здравствуйте, hi_octane, Вы писали:

__>>Я полагаю , что это как раз можно сделать с метаатрибутом.

__>>Знающие люди подскажут насколько такое реально сделать.

_>Да такой вариант возможен, но уже после того как я эту ветку начал, удалось дотумкать ещё до одного вида, который сейчас кажется достаточно простым в реализации, и при этом сохраняет все плюшки автокомплита и интеллисенса:


_>
_>[ExpandToRecord]
_>Func(a : int, b : bool, out c : int, out m : decimal) : void
_>{
_>//здесь компилятор искаропки проследит чтобы возвращаемые значения были правильно заданы, и т.п.
_>}

_>//а аттрибут создаёт пару типов AB и CM, и различные версии функции, которые вызывают основную
_>Func(ab : AB) : CM
_>{  
_>  def cm = CM();
_>  Func(ab.a, ab.b, out cm.c, out cm.m);
_>  cm;
_>}

_>Func(ab : AB, out c : int, out m : decimal) : void
_>{ 
_>}

_>Func(a : int, b : bool) : CM
_>{
_>}
_>


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

_>Получив кучу версий, можно весьма свободно управлять данными, и при этом иметь автокомплит, интеллисенс, вывод типов и прочие. И, судя по всему, вообще не меняя ничего в компиляторе.


_>Но вот как быть с типизированными индексами массивов пока не знаю Частную задачу из одних массивов решать не хочется. Круто было бы если бы удалось совместно с кем-то продумать и ввести в язык "макротипы", которые ведут себя совсем как настоящие, но на какой-то из последних стадий разворачиваются в то, во что сами решат. Но тут нужно тотальную ревизию понятия "тип" проводить, и не факт что я с этим справлюсь.


ОООо идея с макротипамми это +100 !!
Re[2]: Именованные туплы и более типизированные массивы
От: BogdanMart Украина  
Дата: 06.03.11 12:09
Оценка:
Оказалось это ограничение фреймворка, енум хоть и написано что от инта наследуется но он наследуется от енума на самом деле.
Вот рабочий пример:
  public enum Idx : int {}
  
  public class MyList[Tindex,Tval]
    where Tindex : ValueType

  {
    static this()
    {
      def typ = typeof(Tindex); 
      unless (typ.Equals(typeof(int)) || typ.IsEnum)
        throw System.ArgumentException();
    }    
    
    _l : array[Tval];
    public this(size : int)
    {
      _l = array(size);
    }
    
    public Item[index : Tindex] : Tval
    {
      get
      {
        _l[index :> int]
      }
      set
      {
        _l[index :> int] = value;
      }
    }    
  }

      def l = MyList.[int,int](5);
      l[0] = 5;
      
      def l = MyList.[Idx,int](5);
      l[1 :> Idx] = 5;
      
      def l = MyList.[double,int](5); // тут будет Ексепшн, что тип  недопустим
Re: Именованные туплы и более типизированные массивы
От: _nn_ www.nemerleweb.com
Дата: 06.03.11 15:40
Оценка:
Здравствуйте, hi_octane, Вы писали:
_>2. Сильная типизация алиасов, с типизацией индексов массивов:
_>
_>type Idx = int;
_>type Idy = int;
_>type Idz = int;
_>


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

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

strong type Idx = int;

=>
class Idx
{
  _value : int;

  public this() { }
  public this(value : int) { _value = value; }

  public static @:(o : Idx) : int { _value; }

  ... // Тут уже надо думать что и как делать
}


Сделать, чтобы работало хотя бы для базовых типов.
Как я понимаю этого вам будет достаточно.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Именованные туплы и более типизированные массивы
От: Аноним  
Дата: 06.03.11 15:45
Оценка:
не будет....

надо что бы массив созданный с ними принимал idx, но не принимал int...

у тебя как я понимаю будет принимать int
Re[3]: Именованные туплы и более типизированные массивы
От: Аноним  
Дата: 06.03.11 15:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>не будет....


А>надо что бы массив созданный с ними принимал idx, но не принимал int...


А>у тебя как я понимаю будет принимать int


В C++x0 почти такое есть...

В немерли например нет размерностей переменных....
Re[4]: Именованные туплы и более типизированные массивы
От: _nn_ www.nemerleweb.com
Дата: 06.03.11 16:13
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>не будет....


А>>надо что бы массив созданный с ними принимал idx, но не принимал int...


А>>у тебя как я понимаю будет принимать int


А>В C++x0 почти такое есть...


А>В немерли например нет размерностей переменных....


Что такое размерность переменной ?
Вы про "Семантический контроль над размерностями"
Автор: Oyster
Дата: 05.04.06
?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Именованные туплы и более типизированные массивы
От: hi_octane Беларусь  
Дата: 06.03.11 20:50
Оценка:
Вариант со своими объявлениями и массивов и типов я пробовал, но он не так удобен, несмотря даже на хищение идей из проекта Oyster'a. И получается какая-то ощутимая просадка при использовании индексаторов своего класса, по сравнению с работой с массивом напрямую. А хочется идеального решения навека, так чтобы и рыбку съесть и аквариум выпить
Re: Именованные туплы и более типизированные массивы
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.03.11 07:56
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>1. Именованные туплы, а лучше именование параметров Generic'ов:


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

_>2. Сильная типизация алиасов, с типизацией индексов массивов:


Для этого нужно менять компилятор. На Н2 такая фича запланирована. На Н1 нет. Но если сделаешь, то конечно никто против не будет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Именованные туплы и более типизированные массивы
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.03.11 07:58
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Но пока я разбираюсь с парсером.

WH>Там есть еще куча всего что я хочу сделать.
WH>Это касается как функциональности так и оптимизаций (я знаю как сделать его еще быстрее ).

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

Короче, стране нужен уголь! Даешь!!!
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Именованные туплы и более типизированные массивы
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.03.11 08:03
Оценка:
Здравствуйте, Аноним, Вы писали:

А>а разве в немерли есть сильные алиасы?


Если бы были, то разговора не было бы.

Вообще, они реализуются относительно не сложно даже в рамках Н1. Система типов номинативная, так что все что нужно сделать — это завести еще один TypeInfo который бы вводил новое имя, но при этом все остальные значения просто пробрасывал бы базовому типу. Ну, и в компиляторе нужно подхачить типизацию оператора уточнения типа ":" чтобы там учитывались эти самые алиасы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Именованные туплы и более типизированные массивы
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.03.11 08:17
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>
WH>      identifierStartCharacter  = [hint: 'a'..'z' + 'A'..'Z' + '_'] (letterCharacter / "_");
WH>      identifierPartCharacters  = [hint: 'a'..'z' + 'A'..'Z' + '_' + '0'..'9'] (letterCharacter / decimalDigitCharacter / connectingCharacter / combiningCharacter / formattingCharacter);
WH>

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

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

В то же время нам очень нужна расширяемость, приоритеты и возможность начинать парсинг с произвольного правила грамматики (это нужно для реализации квази-цитирования).

И тратить сейчас время на хинты не самое разумное решение. Лучше сделать это позже.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Именованные туплы и более типизированные массивы
От: _Eter_ http://mnazarov.ru
Дата: 07.03.11 12:38
Оценка:
Здравствуйте, Аноним, Вы писали:

А>не будет....


А>надо что бы массив созданный с ними принимал idx, но не принимал int...


А>у тебя как я понимаю будет принимать int


Можно создавать обертки над массивами с нужными индексаторами
Re[2]: Именованные туплы и более типизированные массивы
От: hi_octane Беларусь  
Дата: 07.03.11 13:50
Оценка:
VD>То есть на выходе обычный не именованный кортеж, но внутри можно пользоваться именами? Это можно и макросом реализовать.
На выход тоже именованные. Т.е. хочется record types с явным объявлением не только типов но и имён возвращаемых значений в заголовке функции. Ну и далее в местах использования чтобы из автокомплита было видно не только типы но и имена. Потому что смотреть в заголовок функции и видеть func() : int*int*int это совсем не так наглядно как func() : (localIndex : int, hashCode : int, sign : int).

Насчёт макроса согласен, и даже простецкий аналог на out уже кустарно слепил, тут краткое описание
Автор: hi_octane
Дата: 06.03.11
. Для старта вроде хватит, может позже до более красивого синтаксиса без макроса доберусь.

_>>2. Сильная типизация алиасов, с типизацией индексов массивов:

VD>Для этого нужно менять компилятор. На Н2 такая фича запланирована. На Н1 нет. Но если сделаешь, то конечно никто против не будет.

Вот нужно хоть примерную оценку насколько эти изменения будут сложны для Н1 (хоть с потолка цифру скажи , а я уже доуточню в процессе), т.е. что будет эффективнее — вложить допустим один месяц и добавить это в Н1, или вложить тот же месяц в Н2, и получить эти же фичи на существенно лучшей базе?
Re[8]: Именованные туплы и более типизированные массивы
От: hi_octane Беларусь  
Дата: 07.03.11 13:56
Оценка:
VD>Вообще, они реализуются относительно не сложно даже в рамках Н1. Система типов номинативная, так что все что нужно сделать — это завести еще один TypeInfo который бы вводил новое имя, но при этом все остальные значения просто пробрасывал бы базовому типу. Ну, и в компиляторе нужно подхачить типизацию оператора уточнения типа ":" чтобы там учитывались эти самые алиасы.

Вот, значит всё не так сложно. Завернуть TypeInfo реального типа в "strong type" TypeInfo я думаю смогу. Может сможешь подсказать, оптимальное место, где и на каком этапе выполнять разворачивание назад и подстановку реального типа, так чтобы ничего не сломать?
Re[3]: Именованные туплы и более типизированные массивы
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.03.11 18:05
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>На выход тоже именованные. Т.е. хочется record types с явным объявлением не только типов но и имён возвращаемых значений в заголовке функции.


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


_>Ну и далее в местах использования чтобы из автокомплита было видно не только типы но и имена. Потому что смотреть в заголовок функции и видеть func() : int*int*int это совсем не так наглядно как func() : (localIndex : int, hashCode : int, sign : int).


А почему не завести класс?

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


Это зависит от того кто и с каким усердием делать будет если напрячься, то думаю, за пару дней можно сделать. Если вдруг решишь делать, то создавай брэнч.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Именованные туплы и более типизированные массивы
От: BogdanMart Украина  
Дата: 07.03.11 18:09
Оценка:
Здравствуйте, hi_octane, Вы писали:

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


Как бы на текущем состоянии Н2 не умеет абсолютно ничего
Re[4]: Именованные туплы и более типизированные массивы
От: hi_octane Беларусь  
Дата: 07.03.11 18:51
Оценка:
VD>По этому поводу уже много раз говорено. Полноценные записи невозможны в дотнете, так как рантайм не обеспечивает структурной совместимости типов.

А может можно выкрутиться эмуляцией полноценных записей в уме компилятора, а на какой-нить из последних стадий комплияции — свести всё к туплам? Ведь с дженериками для .NET 1.0 что-то подобное делали.
Re[5]: Именованные туплы и более типизированные массивы
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.03.11 21:50
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>А может можно выкрутиться эмуляцией полноценных записей в уме компилятора, а на какой-нить из последних стадий комплияции — свести всё к туплам? Ведь с дженериками для .NET 1.0 что-то подобное делали.


Когда я спросил "То есть на выходе обычный не именованный кортеж" мне было сказано "На выход тоже именованные". В общем, я ничего не понимаю.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Именованные туплы и более типизированные массивы
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.03.11 21:59
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>Вот, значит всё не так сложно. Завернуть TypeInfo реального типа в "strong type" TypeInfo я думаю смогу. Может сможешь подсказать, оптимальное место, где и на каком этапе выполнять разворачивание назад и подстановку реального типа, так чтобы ничего не сломать?


Разворачивать надо при генерации IL-а или на стадиях T3-T4.

Только не все так просто. Еще нужно синтаксис придумать, распарсить его, придумать формат описания этого типа в сборках, ну и реализовать запись и считывание его в/из сборок. Что касается сборок, то можно сделать так же как это сделано с алиасом (type-ом). Подвесить атрибут на интерфейс и потом его специальным образом интерпретировать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Именованные туплы и более типизированные массивы
От: BogdanMart Украина  
Дата: 07.03.11 22:02
Оценка:
Здравствуйте, VladD2, Вы писали:

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


_>>А может можно выкрутиться эмуляцией полноценных записей в уме компилятора, а на какой-нить из последних стадий комплияции — свести всё к туплам? Ведь с дженериками для .NET 1.0 что-то подобное делали.


VD>Когда я спросил "То есть на выходе обычный не именованный кортеж" мне было сказано "На выход тоже именованные". В общем, я ничего не понимаю.


Грубо говоря ему надо возможность In place создания рекордов.
Re[3]: Именованные туплы и более типизированные массивы
От: Аноним  
Дата: 09.03.11 07:51
Оценка:
Если не тайна, какими именно вычислениями занят?
Re[10]: Именованные туплы и более типизированные массивы
От: Аноним  
Дата: 09.03.11 09:19
Оценка:
Здравствуйте, VladD2, Вы писали:

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


_>>Вот, значит всё не так сложно. Завернуть TypeInfo реального типа в "strong type" TypeInfo я думаю смогу. Может сможешь подсказать, оптимальное место, где и на каком этапе выполнять разворачивание назад и подстановку реального типа, так чтобы ничего не сломать?


VD>Разворачивать надо при генерации IL-а или на стадиях T3-T4.


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


Можно взять реализацию из F#, в его сборках есть такое, как то не форума писали, что добавят в нет5
Re[4]: Именованные туплы и более типизированные массивы
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.03.11 10:44
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>Вариант со своими объявлениями и массивов и типов я пробовал, но он не так удобен, несмотря даже на хищение идей из проекта Oyster'a. И получается какая-то ощутимая просадка при использовании индексаторов своего класса, по сравнению с работой с массивом напрямую. А хочется идеального решения навека, так чтобы и рыбку съесть и аквариум выпить


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

Откровенно говоря я не вижу как сделать так чтобы можно было задавать типы для индексов массива. Все же это встроенный тип. Если ввести псевдонимы для типов индексов еще не сложно, то ввести пользовательские массивы с произвольным типом индекса уже не так тривиально.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Именованные туплы и более типизированные массивы
От: BogdanMart Украина  
Дата: 09.03.11 13:55
Оценка:
Здравствуйте, VladD2, Вы писали:

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


может быть тест проводился в отладочной версии кода под отладчиком. Если запускать релиз без отладчика, то оно ПО ИДЕИ должно инлайниться
Re[6]: Именованные туплы и более типизированные массивы
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.03.11 15:30
Оценка:
Здравствуйте, BogdanMart, Вы писали:

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


BM>может быть тест проводился в отладочной версии кода под отладчиком. Если запускать релиз без отладчика, то оно ПО ИДЕИ должно инлайниться


Кто они? Как не инлайнь, но от оверхэда создаваемого проверками выхода индекса за пределы диапазона массива ты не избавишься. Дотнет знает только один очень примитивный паттерн — перебор элементов массива — в котором он умеет устранять эту проверку (выносить ее за пределы цикла). Если создать обертку, то ты сразу сделаешь эту оптимизацию невозможной.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Именованные туплы и более типизированные массивы
От: hi_octane Беларусь  
Дата: 09.03.11 20:10
Оценка:
А>Если не тайна, какими именно вычислениями занят?
Увы, проект и заказчик, под NDA Хоть и не слишком суровым (т.е. не оборонка какая), так что какие-то технологические вещи можно будет обсуждать, но только после релиза.
Re[6]: Именованные туплы и более типизированные массивы
От: Воронков Василий Россия  
Дата: 10.03.11 11:53
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Когда я спросил "То есть на выходе обычный не именованный кортеж" мне было сказано "На выход тоже именованные". В общем, я ничего не понимаю.


Это все равно не отменяет возможности разруливать такие вещи исключительно на этапе компиляции. Скажем, у тебя по-прежнему формируется кортеж, но со специальным атрибутом, через который задается соответствие индексов и полей. Для старых версий компилятора это будет просто кортеж и ничего более. Новая версия — определит, что это кортеж непростой, а с атрибутом, и на основе данных этого атрибута превратит при компиляции запись вида "foo.bar" в "foo[2]".

Впрочем, возникает подозрение, что это немало работы
Re[7]: Именованные туплы и более типизированные массивы
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.03.11 13:01
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

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


Атрибут нельзя повесить на объект (экземпляр типа). Мы можем повесить атрибут на метод возвращающий кортеж или на тип. Но если у нас есть тип, то не ясно зачем в нем что-то делать атрибутами.

Получается, что атрибут должен вешаться на метод. И выглядеть это должно как-то так. Предположим, что мы имеет засахареный код:
[return: RecordInfo("Id Name Birthday")]
SomeMethod(person : Record[Id : int, Name : string, Birthday : DateTime]) : Record[Id : int, Name : string, Birthday : DateTime]
{
  person
}

Тогда его рассахаренная версия будет выглядеть так:
[return: RecordInfo("Id Name Birthday")]
SomeMethod([RecordInfo("Id Name Birthday")] person : int * string * DateTime) : int * string * DateTime
{
  ...
}


А применение что-то вроде этого:
def person = SomeMethod(Record(Id=42, Name="Вася", Birthday=DateTime(1974, 4, 25)));

WriteLine($"Идентификатор: $(person.Id) Имя: $(person.Name) Дата рождения: $(person.Name)");

Это дело переписывается (рассахаривается) во что-то вроде (но с альфа-переименованием):
def (Id, Name, Birthday) = SomeMethod((42, "Вася", DateTime(1974, 4, 25)));

WriteLine($"Идентификатор: $Id Имя: $Name Дата рождения: $Name");


ВВ>Для старых версий компилятора это будет просто кортеж и ничего более. Новая версия — определит, что это кортеж непростой, а с атрибутом, и на основе данных этого атрибута превратит при компиляции запись вида "foo.bar" в "foo[2]".


Еще раз. Атрибут нельзя повесить на воздух.

ВВ>Впрочем, возникает подозрение, что это немало работы


Ага. Без хака компилятора это в Немерле 1.0 вообще вряд ли можно сделать.

И не очень много толку, если честно.

Разве что такое будет удобно при работе с линком. А так у нас уже есть анонимные типы в виде макроса.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Именованные туплы и более типизированные массивы
От: Воронков Василий Россия  
Дата: 10.03.11 13:17
Оценка:
Здравствуйте, VladD2, Вы писали:

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

VD>Атрибут нельзя повесить на объект (экземпляр типа). Мы можем повесить атрибут на метод возвращающий кортеж или на тип. Но если у нас есть тип, то не ясно зачем в нем что-то делать атрибутами.

А для кортежей что, используется Tuple<>? Разве тип не генерится?
Re[9]: Именованные туплы и более типизированные массивы
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.03.11 14:09
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>А для кортежей что, используется Tuple<>? Разве тип не генерится?


Что значит тип генерируется? Кортежи описываются набором дженерик-типов (т.е. Tuple<>, но Майкросовтовский из 4-го фрэймворка, а наш).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Именованные туплы и более типизированные массивы
От: BogdanMart Украина  
Дата: 10.03.11 14:39
Оценка:
Здравствуйте, VladD2, Вы писали:

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


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


BM>>может быть тест проводился в отладочной версии кода под отладчиком. Если запускать релиз без отладчика, то оно ПО ИДЕИ должно инлайниться


VD>Кто они?


Индексаторы JITC'ом, о нем же речь шла.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.