Работы ведутся. С наработками и экспериментами можно ознакомиться тут. Принимаются предложения и критика в любой форме. Особенно приветствуются предложения по именованию, для разрешения конфликов с LINQ.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[4]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, VladD2, Вы писали:
VD>Мне кажется что методы вроде: VD>
VD> public FoldLeft[T](
VD> [NotNull] this arr : array[T],
VD> [NotNull] f : T * T -> T
VD> ) : T
VD>
VD>лучше назвать reduce, чтобы лучше отличать семантику.
Да, я думал об этом. Тем более, что в некоторых ML-ях, в F# например, он именно так и называется.
Есть, кстати, одна проблема: что у FoldLeft, который сейчас в Nemerle, сворачивающая функция принимает элемент коллекции первым аргументом, а аккумулятор — вторым.
По идее, левый фолд должен работать так:
т.е. вообще-то надо бы поменять последовательность аргументов для левой свертки, но это ломающее изменение, череватое довольно неприятными ошибками.
Старые функции для массивов и последовательностей можно оставить в другом пространстве имен, чтобы старый код не ломать, но ведь со списком-то это уже сложнее проделать (хотя можно, если вынести все такие функции методами-расширениями в отдельное пространство имен, а бессмысленные методы списка, вызывающие методы из NList (явный реликт времен без методов-расширений) убрать).
VD>Кроме того FoldLeft настолько часто используется, что стоит ввести для него синоним Fold, или даже вообще отказаться от FoldLeft и использовать для его обозначения FoldLeft.
Да, конечно, у меня запланированы синонимы без Left для FoldLeft, ScanLeft и прочего.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Klapaucius, Вы писали:
K>В этом треде обсуждаются и принимаются пожелания по стандартной библиотеке. А именно по методам расширениям, интерфейсам, операторам, структурам данных, которые нужны вам в стандартной библиотеке, но по какой-то причине туда не включены или реализованы не так как вам нужно. Предложения по макросам пока принимаются где-нибудь в другом месте. Также желательно, я думаю, оформлять свои предложения в виде фич-реквеста в багтрекере.
1. Последовательность (в именовании и не только).
2. Непротиворечивость (чтобы не было конфликтов с тем же System.Linq и 4-ым фрэймворком).
3. Определенность (чтобы все было интуитивно понятно).
4. Обоснованность (изменений и нововведений).
При принятии спорных решений лучше вынести обсуждение на публику (сюда, значич).
Желательно сделать специализированные реализации функций для разных видов коллекций (массивы, списки немерле, списки дотнета, хэш-таблицы) и общую для IEnumerable[T] которая бы динамически вызвала бы специализированные реализации. Например, так сделано для Map2ToArray:
public Map2ToArray[First, Second, Result](
[NotNull] this first : Seq[First],
[NotNull] second : Seq[Second],
[NotNull] func : First * Second -> Result
)
: array[Result]
{
match (first, second)
{
| (f is array[First], s is array[Second]) => Map2ToArray(f, s, func)
| (f is SCG.ICollection[First], s is SCG.ICollection[Second]) => Map2ToArray(f.NToArray(), s.NToArray(), func)
| (f is list[First], s is list[Second]) =>
def foldFunc(left, right, (arr, index))
{
arr[index] = func(left, right);
(arr, index + 1)
}
def (result, _) = f.FoldLeft2(s, (array(f.Length), 0), foldFunc);
result
| _ =>
using (e1 = first.GetEnumerator(), e2 = second.GetEnumerator())
{
def loop (result) : array[Result]
{
match (e1.MoveNext(), e2.MoveNext())
{
| (true, true) => result.Add(func(e1.Current, e2.Current)); loop(result)
| (false, false) => result.NToArray()
| (true, false)
| (false, true) => throw System.ArgumentException("Collections must have the same length", "first, second");
}
}
loop(SCG.List()).NToArray();
}
}
}
public Map2ToArray[First, Second, Result](
[NotNull] this first : array[First],
[NotNull] second : array[Second],
[NotNull] func: First * Second -> Result
)
: array[Result]
{
when (first.Length != second.Length)
throw System.ArgumentException("Collections must have the same length", "first, second");
def result = array(first.Length);
foreach (i in[0 .. first.Length - 1])
result[i] = func(first[i], second[i]);
result;
}
...
В общем, чтобы (если это возможно) лучшая реализация выбиралась компилятором, а тип не известен на стадии компиляции, чтобы универсальная функция выбирала специализированную (по возможности) динамически.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Klapaucius, Вы писали:
K>Принимаются предложения и критика в любой форме.
В Nemerle.Collections.Set[T] надо добавить методы:
IsSupersetOf, IsSubsetOf, IsProperSubsetOf, IsProperSupersetOf (что означает "Proper" я и сам не понимаю, но наверно они тоже нужны). Ну, и возможно другие методы из System.Collections.Generic.HashSet[T].
А то до смешного доходит. Сегодня от лени написал вот такой код:
mutable min = recSets.NFirst();
foreach (s in recSets.Skip(1))
when (HashSet(min).IsSupersetOf(HashSet(s)))
min = s;
и сам же ужаснулся.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: [Lib] Принимаются пожелания по стандартной библиотеке.
Здравствуйте, Klapaucius, Вы писали:
K>В этом треде обсуждаются и принимаются пожелания по стандартной библиотеке. А именно по методам расширениям, интерфейсам, операторам, структурам данных, которые нужны вам в стандартной библиотеке, но по какой-то причине туда не включены или реализованы не так как вам нужно. Предложения по макросам пока принимаются где-нибудь в другом месте. Также желательно, я думаю, оформлять свои предложения в виде фич-реквеста в багтрекере.
Здравствуйте, Klapaucius, Вы писали:
K>В этом треде обсуждаются и принимаются пожелания по стандартной библиотеке. А именно по методам расширениям, интерфейсам, операторам, структурам данных, которые нужны вам в стандартной библиотеке, но по какой-то причине туда не включены или реализованы не так как вам нужно. Предложения по макросам пока принимаются где-нибудь в другом месте. Также желательно, я думаю, оформлять свои предложения в виде фич-реквеста в багтрекере.
Убрать дупликаты и колизии:
Nemerle.Collections.NList.NToList
Nemerle.Collections.NList.ToNList при чем принимает только массив
Nemerle.Core.list.ToList — совпадает с System.Linq.Enumerable.ToList
Nemerle.Core.list.AsList
Нет методов принимающих System.Collections.IEnumerable, однако метод Cast надо брать из System.Linq, уже лишняя зависимость
Здравствуйте, Klapaucius, Вы писали:
K>Работы ведутся. С наработками и экспериментами можно ознакомиться тут. Принимаются предложения и критика в любой форме. Особенно приветствуются предложения по именованию, для разрешения конфликов с LINQ.
В плане наименований / дизайна / используемых функций не смотрели как это сделано в Scala? Не будет ли это лучше, чем смотреть на Haskell? Nemerle всё-таки на Scala больше похож, чем на Haskell.
L>если source является LazyIterator, то должен вызваться специальный метод. Однако я не вижу, почему здесь не будет вечной рекурсии. При проверке is Type в правом выражении переменная автоматически приводится к Type? Как-то неявно это...
source1 : Seq[T]
source2 : LazyIterator[T]
там скорее всего есть перегрузка подобная Tail[T](this source : LazyItertor[T]) : LazyItertor[T]
Re[2]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, lomeo, Вы писали:
L>При проверке is Type в правом выражении переменная автоматически приводится к Type? Как-то неявно это...
Дык это и есть паттерн проверки типа. Он так работает. Если тип соответствует проверяемому, то внутри блока переменная приводится к этому типу. Аналог гардов из Оберона. Да и в Окамле так можно, если не ошибаюсь.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Аноним, Вы писали:
А>Циклы — это императивные конструкции. Выражать из через функнции высшего порядка идеологически не верно.
А>тогда надо уж быть последовательным и требовать чистоту языка.
Не вижу в этом никакой последовательности.
Более того чистота языка — это рекламный ход расчищенный на охмурение серых народных масс. Не бывает чисто функциональных языков просто потому, что весь смысл программ в создании побочных эффектов.
Бывают языки в которых императивный код четко выделен. Смысл в этом есть только если язык имеет ленивую семантику.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, lomeo, Вы писали:
L>При проверке is Type в правом выражении переменная автоматически приводится к Type? Как-то неявно это...
Сори, не сразу понял суть вопроса. Да, приводится и это очень удобно при матчинге базового типа иерархий объектов. Насчет явности вопрос спорный, для меня было бы нелогичным требование приводить переменную к более строгому типу явно, если уже есть гарантия, что она ему соответствует.
Re[8]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, VladD2, Вы писали:
VD>Откровенно говоря по мне так все эти Iter-ы нужно просто выбросить.
Я полностью согласен с тем, что императивный код лучше отделать явно, но я часто применяю такой паттерн:
def processItem(item)
{
//код обработки отдельного айтема вынесен чтобы не захламлять основной алгоритм
}
// основной алгоритм
...
items.Iter(processItem);
...
Превращать последнюю строчку в
foreach (item in items)
processItem(item)
очень не хочется
В C# я не использую такой подход, т.к. там нет локальных функций. Там полностью оправдано отсутствие Iter. Можно конечно еще допилить foreach для краткой записи Iter, но я и так не могу запомнить все его возможности.
Либо написать макру типа.
apply processItem on items;
Все же, мне кажется, меньшим злом будет оставить Iter.
Re[3]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Klapaucius, Вы писали:
K>В этом треде обсуждаются и принимаются пожелания по стандартной библиотеке. А именно по методам расширениям, интерфейсам, операторам, структурам данных, которые нужны вам в стандартной библиотеке, но по какой-то причине туда не включены или реализованы не так как вам нужно. Предложения по макросам пока принимаются где-нибудь в другом месте. Также желательно, я думаю, оформлять свои предложения в виде фич-реквеста в багтрекере.
Может лучше переименовать MaxIndex в UpperBound?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
[Lib] Принимаются пожелания по стандартной библиотеке.
В этом треде обсуждаются и принимаются пожелания по стандартной библиотеке. А именно по методам расширениям, интерфейсам, операторам, структурам данных, которые нужны вам в стандартной библиотеке, но по какой-то причине туда не включены или реализованы не так как вам нужно. Предложения по макросам пока принимаются где-нибудь в другом месте. Также желательно, я думаю, оформлять свои предложения в виде фич-реквеста в багтрекере.
... << RSDN@Home 1.2.0 alpha 4 rev. 1446>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[3]: [Lib] Принимаются пожелания по стандартной библиотеке
K>Принимаются предложения и критика в любой форме. Особенно приветствуются предложения по именованию, для разрешения конфликов с LINQ.
Мне кажется что методы вроде:
public FoldLeft[T](
[NotNull] this arr : array[T],
[NotNull] f : T * T -> T
) : T
лучше назвать reduce, чтобы лучше отличать семантику.
Кроме того FoldLeft настолько часто используется, что стоит ввести для него синоним Fold, или даже вообще отказаться от FoldLeft и использовать для его обозначения FoldLeft.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Klapaucius, Вы писали:
K>Да, я думал об этом. Тем более, что в некоторых ML-ях, в F# например, он именно так и называется. K>Есть, кстати, одна проблема: что у FoldLeft, который сейчас в Nemerle, сворачивающая функция принимает элемент коллекции первым аргументом, а аккумулятор — вторым.
Да, да, много раз натыкался. Потому никак запомнить не могу их порядок.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[3]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, hardcase, Вы писали:
H>>Как успехи?
K>Работы ведутся. С наработками и экспериментами можно ознакомиться тут. Принимаются предложения и критика в любой форме. Особенно приветствуются предложения по именованию, для разрешения конфликов с LINQ.
А почему MapSeq имеет двойника MapISeq, а Iter просто перегружен?
Re[4]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, catbert, Вы писали:
C>>А почему MapSeq имеет двойника MapISeq, а Iter просто перегружен?
K>Извините, не понял.
Ээ, это я буковки не увидел, извините
Re[4]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, catbert, Вы писали:
VD>>(что означает "Proper" я и сам не понимаю, но наверно они тоже нужны).
C>"Proper" означает "строгий" (ну, то есть {A, B} не является строгим подмножеством {A, B}).
Какая-то дурацкая терминология. Мне кажется логично было бы называть это эксклюзивным или нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, SergASh, Вы писали:
SAS>Это математическая терминология, она постарше нас будет, так что лучше ее не клеймить. Подумай об аналогии со строгим и нестрогим неравенством.
Я всегда не доверял английским спец шко... математической терминалогии. Складывается ощущине, что люди специально шыфруются.
В программировании традиции именования почерпнутые из математики неизменно приводят к проблемам.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, _nn_, Вы писали:
VD>>Откровенно говоря по мне так все эти Iter-ы нужно просто выбросить.
__>Из-за худшей генерации кода по сравнению с макросом ?
Из-за многих факторов. Главный, пожалуй, идеологический. Циклы — это императивные конструкции. Выражать из через функнции высшего порядка идеологически не верно.
Ну, и скорость конечно тоже влияет. Циклы зачастую бывают очень мелкими. При этом нет смысла тратить время на создание лямбды и косвенные вызовы.
__>Они удобны в некоторых местах: __>
__>a.Iter(WriteLine);
__>
__>vs __>
__>foreach (i in a)
__> WriteLine(i);
__>
Никакого удобства тут нет. Ну, съели мы промежуточные переменные и что?
При отладке — это серьезный минус, так как колстек забивается грязью и на значение посмотреть труднее.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: [Lib] Принимаются пожелания по стандартной библиотеке
От:
Аноним
Дата:
05.10.10 12:52
Оценка:
Циклы — это императивные конструкции. Выражать из через функнции высшего порядка идеологически не верно.
тогда надо уж быть последовательным и требовать чистоту языка.
Re[7]: [Lib] Принимаются пожелания по стандартной библиотеке
От:
Аноним
Дата:
06.10.10 06:34
Оценка:
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Аноним, Вы писали:
А>>Циклы — это императивные конструкции. Выражать из через функнции высшего порядка идеологически не верно.
А>>тогда надо уж быть последовательным и требовать чистоту языка.
VD>Не вижу в этом никакой последовательности.
VD>Более того чистота языка — это рекламный ход расчищенный на охмурение серых народных масс. Не бывает чисто функциональных языков просто потому, что весь смысл программ в создании побочных эффектов.
VD>Бывают языки в которых императивный код четко выделен. Смысл в этом есть только если язык имеет ленивую семантику.
спасибо за пояснение.
Re: [Lib] Принимаются пожелания по стандартной библиотеке.
Почему такой c одной стороны не труъ функциональный код? Например функция FoldLeft:
public FoldLeftI[TAccumulator, T](
[NotNull] this lst : list[T],
mutable acc : TAccumulator,
[NotNull] f : int * TAccumulator * T -> TAccumulator
) : TAccumulator
{
foreach (value in lst with i)
acc = f(i, acc, value);
acc
}
C другой стороны мозговыносящие конструкции на конструкторах списков:
#warning not commented
#warning not tested
public Concatenate[T](
[NotNull] this lists : list[list[T]],
) : list[T]
{
$[ item | items in lists, item in items ]
}
Это же стандартная библиотека — образец так сказать.
Re[2]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Ka3a4oK, Вы писали:
KK>Это же стандартная библиотека — образец так сказать.
Стандартная библиотека никогда не является образцом кода.
Она всегда должна быть вхлам заоптимизирована.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Ka3a4oK, Вы писали:
KK>>Это же стандартная библиотека — образец так сказать. WH>Стандартная библиотека никогда не является образцом кода. WH>Она всегда должна быть вхлам заоптимизирована.
Ну и в чем там оптимизация по-сравнению с рекурсивным вызовом, который должен развернуться в цикл? Мы говорим: извините, у нас рекрусия разворачивается не очень, поэтому мы вручную разворачиваем рекурсию.
Re[4]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Ka3a4oK, Вы писали:
KK>Ну и в чем там оптимизация по-сравнению с рекурсивным вызовом, который должен развернуться в цикл? Мы говорим: извините, у нас рекрусия разворачивается не очень, поэтому мы вручную разворачиваем рекурсию.
Вообще то это циклы в рекурсию разворачиваются...
А потом на этапе генерации кода рекурсия разворачивается в циклы.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Ka3a4oK, Вы писали:
KK>>Ну и в чем там оптимизация по-сравнению с рекурсивным вызовом, который должен развернуться в цикл? Мы говорим: извините, у нас рекрусия разворачивается не очень, поэтому мы вручную разворачиваем рекурсию. WH>Вообще то это циклы в рекурсию разворачиваются... WH>А потом на этапе генерации кода рекурсия разворачивается в циклы.
Тем более не вижу в чем тут оптимизация.
Re[6]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Ka3a4oK, Вы писали:
KK>Почему такой c одной стороны не труъ функциональный код? Например функция FoldLeft:
Данная конкретная функция — это та же самая функция FoldLeftI, что и для энумераторов и массивов — т.е. функция, которая уже отлажена и работает.
В общем же случае есть тенденция использовать foreach по той причине, что это самый развитый макрос, в который добавлена масса удобных фич, и потому код с ним получается короче и производительнее. Лист компрехеншн менее развит, а используя рекурсию я остаюсь с полностью рассахаренным немерле, с необходимостью писать вручную весь бойлерплейт по обходу коллекции и, — как следствие — наибольшим объемом кода и наибольшей вероятностью сделать ошибку.
KK>C другой стороны мозговыносящие конструкции на конструкторах списков:
Я не вижу в лист компрешеншене ничего мозговыносящего. Лично для меня это стоящий на втором месте способ написать что-то красиво и читабельно.
Если бы в Немерле этот макрос был развит, генерировал производительный код, обладал полезными расширениями вроде хаскелевских и работал для энумераторов и массивов я бы везде его и использовал.
KK>Это же стандартная библиотека — образец так сказать.
Нет. Так писать прикладной код, как пишут библиотечный код нельзя. Читаемость библиотечного кода слишком сильно страдает от оптимизаций.
Вот пример.
Как бы я написал функцию Choose:
source.Map(f).CatOptions()
Именно так, по моему мнению, и нужно писать на ФЯ — используя комбинаторы. Но компилятор не делает дефорестацию и тут будет промежуточный список, а потому так написать библиотечную функцию я не могу.
Мой следующий выбор — лист компрехеншн.
$[ x | Some(x) in $[ f(y) | y in source ]]
Хуже, чем первый вариант, но тоже ничего. К сожалению, макрос недоделан и не разворачивает это в один цикл, а порождает промежуточный список, без которого можно бы было и обойтись.
Тогда приходится писать так:
Все кишки вывалились наружу: и обход списка и работа с option — бочка бойлерплейта с ложкой растворенного смысла.
Но ведь и так написать я не могу. Тут будут конструироваться и деконструироваться кортежи, которые (при условии, что они — value types) JIT может убрать, а может и не убрать (в зависимости от версии CLR с точностью до сервис-пака) — никто ничего не гарантирует.
Так что и так я написать не могу, а вынужден писать так:
Здравствуйте, Klapaucius, Вы писали:
K>Если бы в Немерле этот макрос был развит, генерировал производительный код, обладал полезными расширениями вроде хаскелевских
А что там в Хаселе такого есть, что у нас нет?
K>и работал для энумераторов и массивов я бы везде его и использовал.
Ну, это ты можешь сам сделать. В качестве примера можно взять код форыча.
K>Нет. Так писать прикладной код, как пишут библиотечный код нельзя. Читаемость библиотечного кода слишком сильно страдает от оптимизаций.
+1
K>7 LLOC нечитабельной рекурсивной лапши вместо 1 LLOC нормального функционального кода.
Но оно того стоит, так как этот код будет вызываться в туче мест, некоторые из которых могут оказаться критичными к производительности.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: [Lib] Принимаются пожелания по стандартной библиотеке.
Здравствуйте, Klapaucius, Вы писали:
K>В этом треде обсуждаются и принимаются пожелания по стандартной библиотеке. А именно по методам расширениям, интерфейсам, операторам, структурам данных, которые нужны вам в стандартной библиотеке, но по какой-то причине туда не включены или реализованы не так как вам нужно. Предложения по макросам пока принимаются где-нибудь в другом месте. Также желательно, я думаю, оформлять свои предложения в виде фич-реквеста в багтрекере.
Как продвигаются дела? Не пора ли интегрировать результат в стандартную библиотеку?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: [Lib] Принимаются пожелания по стандартной библиотеке
В foreach такого кода нет. Он ничего не порождает (точнее, в случае с yield порождает, конечно, но там компиляторная магия используется), а компрехеншн — выражение, имеющее значение — генерируемую им коллекцию.
K>>7 LLOC нечитабельной рекурсивной лапши вместо 1 LLOC нормального функционального кода. VD>Но оно того стоит, так как этот код будет вызываться в туче мест, некоторые из которых могут оказаться критичными к производительности.
Ну, собственно, об этом и был весь мой пост.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[2]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Klapaucius, Вы писали:
K>В foreach такого кода нет. Он ничего не порождает (точнее, в случае с yield порождает, конечно, но там компиляторная магия используется), а компрехеншн — выражение, имеющее значение — генерируемую им коллекцию.
Да какая разница порождает или нет? Я же говорю "в качестве примера". В foreach ведется работа с разными типами коллекций. Причем не через универсальные интерфейсы, а генерируется специализированный код. Тоже самое нужно сделать и компрешеншоне.
K>>>7 LLOC нечитабельной рекурсивной лапши вместо 1 LLOC нормального функционального кода. VD>>Но оно того стоит, так как этот код будет вызываться в туче мест, некоторые из которых могут оказаться критичными к производительности.
K>Ну, собственно, об этом и был весь мой пост.
Ну, дык я тебя и поддержал
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Klapaucius, Вы писали:
K>Как бы я написал функцию Choose: K>
K>source.Map(f).CatOptions()
K>
K>Именно так, по моему мнению, и нужно писать на ФЯ — используя комбинаторы. Но компилятор не делает дефорестацию и тут будет промежуточный список, а потому так написать библиотечную функцию я не могу.
А нельзя сделать макрос, который приводит source к sequence, над ней делает эти операции, а затем результат обратно приводит к списку? VM не свернёт это в цикл?
И ещё — на макросах, насколько я понимаю, можно написать fusion для подобных выражений.
Re[4]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, lomeo, Вы писали:
L>А нельзя сделать макрос, который приводит source к sequence, над ней делает эти операции, а затем результат обратно приводит к списку? VM не свернёт это в цикл?
В принципе возможно.
Проблема втом, что нужно этому макросу как-то сообщить семантику операций, грубо говоря, передать AST кода Map и CatOptions.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[5]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, hardcase, Вы писали:
H>В принципе возможно. H>Проблема втом, что нужно этому макросу как-то сообщить семантику операций, грубо говоря, передать AST кода Map и CatOptions.
Мы как-то с Камилом думали о введении маросов-расширений, на манер методов-расширений. Выглядеть они должны как обычные методы и разрешение перегрузки для них должно отрабатывать как для обычного метода, но дальше должен вызваться макрос который уже будет генерировать оптимальный код.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, lomeo, Вы писали:
L>В плане наименований / дизайна / используемых функций не смотрели как это сделано в Scala?
Смотрел, спасибо, просто поленился включить в сводную таблицу.
L>Не будет ли это лучше, чем смотреть на Haskell? Nemerle всё-таки на Scala больше похож, чем на Haskell.
Дело в том, что система типов nemerle от системы типов scala очень существенно отличается. На CLR-дженериках библиотеку скалы просто не повторить. А смотрел я (помимо прочего, вроде библиотеки F#) не на haskell вообще, а в основном на Data.List, допотопный модуль, который практически никаких особенностей системы типов хаскеля не использует и может быть портирован на любой язык с первоклассными функциями. Алексей Романов его, например, на C# портировал.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[6]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, VladD2, Вы писали:
VD>Это аналог Async-а.
Ну нет, это такой обобщенный zip, на async совсем не похоже.
VD>А это уж больно на линк смахивает (что у нас так же имеется).
Да, конечно. Но там есть полезные расширения для лист компрехеншн, которые более легковесны синтаксически чем линковские выражения. В данном случае важно то, что это мог бы быть код, преобразующийся в цикл. Линковское выражение же просто выстраивает цепочку методов, принимающих функции, т.е. проблема с падением производительности не решается.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[4]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, lomeo, Вы писали:
L>А нельзя сделать макрос, который приводит source к sequence, над ней делает эти операции, а затем результат обратно приводит к списку? VM не свернёт это в цикл?
VM не свернет.
L>И ещё — на макросах, насколько я понимаю, можно написать fusion для подобных выражений.
В принципе можно, при условии, что есть исходный код этих функций. В общем случае это не так — функции могут быть импортированы из бинарных библиотек.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[5]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Klapaucius, Вы писали:
K>В принципе можно, при условии, что есть исходный код этих функций. В общем случае это не так — функции могут быть импортированы из бинарных библиотек.
Я думаю вполне можно сделать макрос, который аккуратненько спасет их исходный код (PExpr) и позволит добраться до него впоследствии.
/* иЗвиНите зА неРовнЫй поЧерК */
Re: [Lib] Принимаются пожелания по стандартной библиотеке.
Здравствуйте, Klapaucius, Вы писали:
K>В этом треде обсуждаются и принимаются пожелания по стандартной библиотеке. А именно по методам расширениям, интерфейсам, операторам, структурам данных, которые нужны вам в стандартной библиотеке, но по какой-то причине туда не включены или реализованы не так как вам нужно. Предложения по макросам пока принимаются где-нибудь в другом месте. Также желательно, я думаю, оформлять свои предложения в виде фич-реквеста в багтрекере.
Хотелось бы таки выпустить в этом месяце релиз-кондидат. Фактически ждем на сегодня мы завершения работы над поддержкой компиляции C# и новой версии библиотеки.
Что с библиотекой? Ее ведь нужно еще с компилятором и шаблонами проектов/элементов в Интеграции интегрировать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: [Lib] Принимаются пожелания по стандартной библиотеке
, что только к концу месяца планирую ее доделать. Да и это предположительно — у меня все-таки и другие дела есть.
С комментариями не все так радужно, но комментарии можно и к релизу доделать, я потом еще и описание предполагаю сделать, но на русском, надеюсь, если будет нужно, переводчик найдется.
VD>Фактически ждем на сегодня мы новой версии библиотеки.
Виноват.
VD>Хотелось бы таки выпустить в этом месяце релиз-кондидат.
Можно попробовать успеть сделать то, что потом нельзя уже будет поменять (вроде сигнатур функций) пораньше, а потом еще что-нибудь добавить. Тут важно знать, возможны будут еще какие-то работы с библиотекой после выхода релиз-кандидата и насколько они могут быть ломающими. но в любом случае ее до релиза еще тестировать надо, я имею в виду — пользователями тестировать. Тесты у меня есть, но тесты это тесты. Да и отзывов мало, похоже, что стандартная библиотека мало кого интересует.
Да, к слову, есть в Nemerle связывание паттерна с переменной вроде такого:
Здравствуйте, Klapaucius, Вы писали:
K>Можно попробовать успеть сделать то, что потом нельзя уже будет поменять (вроде сигнатур функций) пораньше, а потом еще что-нибудь добавить. Тут важно знать, возможны будут еще какие-то работы с библиотекой после выхода релиз-кандидата и насколько они могут быть ломающими.
Возможно конечно, но все же надо что-то выложить.
K>но в любом случае ее до релиза еще тестировать надо, я имею в виду — пользователями тестировать. Тесты у меня есть, но тесты это тесты. Да и отзывов мало, похоже, что стандартная библиотека мало кого интересует.
Пока она не окажется в общей поставке никаких серьезных откликов ты и не получишь. Потому надо переместить то что есть в Nemerle.dll и начать ее использовать. Тогда и отклик будет.
K>Да, к слову, есть в Nemerle связывание паттерна с переменной вроде такого: K>
Здравствуйте, Klapaucius, Вы писали:
K>С комментариями не все так радужно, но комментарии можно и к релизу доделать, я потом еще и описание предполагаю сделать, но на русском, надеюсь, если будет нужно, переводчик найдется.
Здравствуйте, _nn_, Вы писали:
__>Переводчиков хватит. __>Тут проблемы не будет.
Ну, так предлагаю тогда кому-нить протестировать новую либу и начать переводить коментарии на английский.
Надо уже перетаскивать ее в репозиторий компилятора, если мы ее планируем в релиз включать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, VladD2, Вы писали:
VD>Традиционный вопрос — когда?
Вообще, я на завершающей стадии работы, но эта завершающая стадия месяц уже продолжается — у меня было не очень много времени для работы над библиотекой. Хотя гуглкод утверждает, что активность проекта "высокая", так что значит, что я не очень ленюсь.
И да, кстати, включите мне разрешение на коммит в nemerle, мой гугл-аккаунт на http://code.google.com/p/nemerle-std/ указан.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[4]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Ziaw, Вы писали:
Z>// основной алгоритм Z>... Z>items.Iter(processItem); Z>... Z>[/nemerle]
Z>Превращать последнюю строчку в Z>
Z>foreach (item in items)
Z> processItem(item)
Z>
Z>очень не хочется
Я по началу тоже так мыслил. Со временем пришел к тому, что не фига маскировать императив под ФП.
К тому же у foreach есть ощутимые преимущества. Он всегда инлайнится, что убирает лишний вызов из колстека, делает код быстрее и упрощает отладку (очень существенно).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Klapaucius, Вы писали:
K>И да, кстати, включите мне разрешение на коммит в nemerle, мой гугл-аккаунт на http://code.google.com/p/nemerle-std/ указан.
Я ни разу не подлючал именно гугль-экаунты. У всех до этого были жмэйлы.
Если я правильно понял, твой экаунт это klapaucius.the.constructor?
Я его подключил в коммитеры. Попробуй. Если я ошибся, сообщи мне об этом и напиши точное имя экаунта.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: [Lib] Принимаются пожелания по стандартной библиотеке.
Здравствуйте, Klapaucius, Вы писали:
K>В этом треде обсуждаются и принимаются пожелания по стандартной библиотеке. А именно по методам расширениям, интерфейсам, операторам, структурам данных, которые нужны вам в стандартной библиотеке, но по какой-то причине туда не включены или реализованы не так как вам нужно. Предложения по макросам пока принимаются где-нибудь в другом месте. Также желательно, я думаю, оформлять свои предложения в виде фич-реквеста в багтрекере.
Поглядел исходники. В них используется пространство имен System.Linq и типы от туда (например, Enumerable).
Многие высказывались, что используют 2-ой фрэймворк для развертывания своих приложений. Так что стандартная бибилотека не должна быть основана на библиотеках из 3+ фрэймворков.
Надо бы заменить Enumerable на свой велосипед.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: [Lib] Принимаются пожелания по стандартной библиотеке.
Здравствуйте, Klapaucius, Вы писали:
K>В этом треде обсуждаются и принимаются пожелания по стандартной библиотеке. А именно по методам расширениям, интерфейсам, операторам, структурам данных, которые нужны вам в стандартной библиотеке, но по какой-то причине туда не включены или реализованы не так как вам нужно. Предложения по макросам пока принимаются где-нибудь в другом месте. Также желательно, я думаю, оформлять свои предложения в виде фич-реквеста в багтрекере.
В добавок к методам XxxOrNone нужно бы добавить методы XxxOrDefault.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: [Lib] Принимаются пожелания по стандартной библиотеке.
Здравствуйте, Klapaucius, Вы писали:
K>В этом треде обсуждаются и принимаются пожелания по стандартной библиотеке. А именно по методам расширениям, интерфейсам, операторам, структурам данных, которые нужны вам в стандартной библиотеке, но по какой-то причине туда не включены или реализованы не так как вам нужно. Предложения по макросам пока принимаются где-нибудь в другом месте. Также желательно, я думаю, оформлять свои предложения в виде фич-реквеста в багтрекере.
public Tail[T](
[NotNull] this source : Seq[T]
) : Seq[T]
{
match(source) {
| source is LazyIterator[T] => source.Tail()
| _ => source.TailSeq()
}
}
если source является LazyIterator, то должен вызваться специальный метод. Однако я не вижу, почему здесь не будет вечной рекурсии. При проверке is Type в правом выражении переменная автоматически приводится к Type? Как-то неявно это...
Здравствуйте, Ziaw, Вы писали:
Z>Сори, не сразу понял суть вопроса. Да, приводится и это очень удобно при матчинге базового типа иерархий объектов. Насчет явности вопрос спорный, для меня было бы нелогичным требование приводить переменную к более строгому типу явно, если уже есть гарантия, что она ему соответствует.
Прикол в том, что я принял
| source is LazyIterator => ...
за guard, а не за паттерн из-за использования is — кажется, что это не булево выражение. Соответственно source для меня был старой, а не новой переменной с таким же именем. В Scala этот паттерн выглядит более явно
case source: LazyIterator => ...
Re[4]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, lomeo, Вы писали:
L>за guard, а не за паттерн из-за использования is — кажется, что это не булево выражение. Соответственно source для меня был старой, а не новой переменной с таким же именем. В Scala этот паттерн выглядит более явно L>
L>case source: LazyIterator => ...
L>
Не вижу тут ничего более явного. ":" в немерле — это оператор уточнения типа (не меняющий тип). Он тоже допустим, но скорее всего вызовет ворнинг.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, VladD2, Вы писали:
VD>Не вижу тут ничего более явного. ":" в немерле — это оператор уточнения типа (не меняющий тип). Он тоже допустим, но скорее всего вызовет ворнинг.
Я ничего и не предлагаю. Я объяснил причину, по которой я неверно прочитал код. В Scala это не оператор уточнения типа, в Scala — это объявление переменной source с типом LazyIterator[T], которая сравнивается с выражением под match. Nemerle — не Scala, но синтаксис очень схож, это и ввело меня в заблуждение.
Re[4]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, lomeo, Вы писали:
L>Прикол в том, что я принял L>
L>| source is LazyIterator => ...
L>
L>за guard, а не за паттерн из-за использования is — кажется, что это не булево выражение. Соответственно source для меня был старой, а не новой переменной с таким же именем. В Scala этот паттерн выглядит более явно L>
L>case source: LazyIterator => ...
L>
В C# и немерле "is" как раз булево выражение, а ":" в данном случае будет upcast (или downcast, все время путаю где там верх, где низ). Вобщем приведение к менее строгому типу.
Re[5]: [Lib] Принимаются пожелания по стандартной библиотеке
Z>В C# и немерле "is" как раз булево выражение, а ":" в данном случае будет upcast (или downcast, все время путаю где там верх, где низ). Вобщем приведение к менее строгому типу.
: — это указание типа (мнемоническое правило: двоеточие используется при объявлении). :> — это приведение типа (от общего к частному).
Когда-то в шаблонах вместо is использовался :>
/* иЗвиНите зА неРовнЫй поЧерК */
Re[5]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Ziaw, Вы писали:
Z>В C# и немерле "is" как раз булево выражение,
На самом деле это не так. "is" в Немерле — это паттерн, а не булево выражение. Но смысл, да, близкий.
Z>а ":" в данном случае будет upcast (или downcast, все время путаю где там верх, где низ). Вобщем приведение к менее строгому типу.
В данном случае это тоже не соввсем верно. ":" в паттерн-матчинге — это старый синтаксис для is. Его пометили как деприкейтед именно потому, что его действие шло в разрез со смыслом оператора ":" в языке. Так что впринципе upcast тоже будет работать:
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, hardcase, Вы писали:
H>>Когда-то в шаблонах вместо is использовался :>
VD>В каких еще шаблонах? И когда это такое было? Мне кажется, ты что-то путаешь.
А, ну значит двоеточие. Я эти времена не застал, просто видел мельком в исходниках.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[6]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, VladD2, Вы писали:
VD>На самом деле это не так. "is" в Немерле — это паттерн, а не булево выражение. Но смысл, да, близкий.
хм... был уверен, что булево а почему оно не возвращает bool? мне видится код ниже нелогичным, есть какие-то причины?
def s = "";
def test1 = if (s is string) true else false; // test1 : booldef test2 = s is string; // test2 : string
VD>В данном случае это тоже не соввсем верно. ":" в паттерн-матчинге — это старый синтаксис для is. Его пометили как деприкейтед именно потому, что его действие шло в разрез со смыслом оператора ":" в языке. Так что впринципе upcast тоже будет работать:
эх... нужна внятная дока и спека по языку
Re[7]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Ziaw, Вы писали:
Z>хм... был уверен, что булево а почему оно не возвращает bool? мне видится код ниже нелогичным, есть какие-то причины? Z>
Z>def s = "";
Z>def test1 = if (s is string) true else false; // test1 : bool
Z>def test2 = s is string; // test2 : string
Z>
Это уже использование аналогичного по имени макроса. Но этот макрос несколько сложнее нежели оператор шарпа. В нем допускается паттерн-матчинг. Например:
using System.Console;
def value : option[_] = Some(1);
WriteLine(value is Some(_)); // True
WriteLine(value is Some(1)); // True
WriteLine(value is Some(2)); // False
Более того оператор when тоже особым образом понимает этот оператор, так что можно писать даже так:
using System.Console;
def value : option[_] = Some(1);
when (value is Some(x))
WriteLine(x); // 1
Z>эх... нужна внятная дока и спека по языку
Сделаем. Можешь присоединяться, кстати . Язык Nemerle задумывался как книга-учебник-мануал. Я хочу сделать так... Дописать еще две части к ней. Одна будет посвящена ООП, а вторая макросам. Оставшаяся часть будет документацией в стиле QuickC (лучшей, на мой взгляд, образец документации). Она будет выстроена в форме: Фича -> краткое описание -> короткий пример.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Ziaw, Вы писали:
Z>Здравствуйте, VladD2, Вы писали:
VD>>На самом деле это не так. "is" в Немерле — это паттерн, а не булево выражение. Но смысл, да, близкий.
Z>хм... был уверен, что булево а почему оно не возвращает bool? мне видится код ниже нелогичным, есть какие-то причины? Z>
Z>def s = "";
Z>def test1 = if (s is string) true else false; // test1 : bool
Z>def test2 = s is string; // test2 : string
Z>
Почему второе строка? Оба выражения возвращают булеан. Просто в том виде что ты привел они вообще вряд ли работают, так как тип известен на этапе компиляции. А вот так:
def s : object = "";
def test1 = if (s is string) true else false; // test1 : booldef test2 = s is string;
WriteLine(test1.GetType());
WriteLine(test2.GetType());
должно работать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, VladD2, Вы писали:
VD>Почему второе строка? Оба выражения возвращают булеан. Просто в том виде что ты привел они вообще вряд ли работают, так как тип известен на этапе компиляции. А вот так: VD>
VD>def s : object = "";
VD>def test1 = if (s is string) true else false; // test1 : bool
VD>def test2 = s is string;
VD>WriteLine(test1.GetType());
VD>WriteLine(test2.GetType());
VD>
VD>должно работать.
Да все ок, где-то я облажался в тесте, но я его уже убил .
Re[4]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, VladD2, Вы писали:
VD>Я ни разу не подлючал именно гугль-экаунты. У всех до этого были жмэйлы.
По-моему, это одно и то же.
VD>Если я правильно понял, твой экаунт это klapaucius.the.constructor? VD>Я его подключил в коммитеры. Попробуй. Если я ошибся, сообщи мне об этом и напиши точное имя экаунта.
Все в порядке. По крайней мере, я теперь числюсь коммитером.
VD>Ну, так может поднажмешь?
Да, но вообще мне нужно на многих фронтах поднажать, помимо этого.
VD>Или возьмешь кого-то в помощники?
А что, есть желающие мне помогать?
VD>Я очень хочу до конца года выолжить релиз-кандидат в который хочу включить и эту библиотеку. А то не будет реальных откликов.
Я, конечно, постараюсь, но ничего гарантировать не могу.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[2]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, VladD2, Вы писали:
VD>Поглядел исходники. В них используется пространство имен System.Linq и типы от туда (например, Enumerable). VD>Многие высказывались, что используют 2-ой фрэймворк для развертывания своих приложений. Так что стандартная бибилотека не должна быть основана на библиотеках из 3+ фрэймворков.
Это, конечно, плохо. Придется писать свой HashSet.
VD>Что такое SeqSeq в таблице API?
Там перечислены методы с окончанием Seq (т.е. не обобщенные версии, которые выбирают конкретную реализацию, а именно версии для IEnumerable. Многие из них я вообще сделаю private или internal) из модуля Seq.
Это автогенерируемая таблица для моего собственного удобства. главное — не нужно думать, что для окончания работы нужны плюсы во всех клетках. Надо будет, наверное, указать то, что планируется реализовать, а то такая таблица может постороннего наблюдателя дизориентировать.
VD>Может лучше переименовать MaxIndex в UpperBound?
Я думал об этом, это был первоначальный вариант, но тут из названия не ясно, верхняя граница включительно или не включительно, т.е. можно ли обращаться по индексу равному UpperBound. А в случае MaxIndex это очевидно. Поскольку весь смысл этого метода — возможность писать
i in [0 .. arr.MaxIndex()]
а не
i in [0 .. arr.Length-1]
я решил что MaxIndex лучше, хотя это вопрос дискуссионный, конечно.
VD>В добавок к методам XxxOrNone нужно бы добавить методы XxxOrDefault.
Да, для быстрых операций вроде Head это имеет смысл, там накладные расходы при использовании WithDefault вроде конструирования и деконструкции option будут заметны.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[3]: [Lib] Принимаются пожелания по стандартной библиотеке
Здравствуйте, Klapaucius, Вы писали:
K>Это, конечно, плохо. Придется писать свой HashSet.
Да, но его можно написать на базе хэш-таблицы. Я сейчас в компиляторе частенько ее использую вместо HashSet-а. А при переходе на 4-й фрэймворк можно подставить базовым классом стандартный HashSet.
VD>>Может лучше переименовать MaxIndex в UpperBound?
K>Я думал об этом, это был первоначальный вариант, но тут из названия не ясно, верхняя граница включительно или не включительно, т.е. можно ли обращаться по индексу равному UpperBound. А в случае MaxIndex это очевидно.
Может я конечно очень давно живу, но как-то еще со времен Васика привык что Bound — это граница. А для длинны обычно Length используется.
VD>>В добавок к методам XxxOrNone нужно бы добавить методы XxxOrDefault.
K>Да, для быстрых операций вроде Head это имеет смысл, там накладные расходы при использовании WithDefault вроде конструирования и деконструкции option будут заметны.
Это для всех методов полезно будет. Во-первых, иногда приходится и скорость выжимать, а создание объектов (option[]) точно ее не добавляет. Во-вторых, частенько бывает так, что default() — это то что нужно в качестве стартового значения. Например, для целых "0" почти всегда хорошо подходит. Получается меньше писанины.
ЗЫ
В ближайшее время хотим выложить релиз-кандитат. Было бы здорово если бы ты к этому времени таки перенес библиотеку в Nemerle.dll.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.