Re[8]: Facebook и язык D - первый шаг наверх.
От: FR  
Дата: 22.10.13 19:08
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>По факту D Range нормально подходит только для SinglePass.


Пока остальное отпущу.

Но по этому у нас кажется сильное недопонимание, основной плюсs range это легкая
комбинируемость функций с ними работающих и ленивость, все это по моему легко
перекрывает недостатки.

import std.stdio;
import std.range;
import std.algorithm;

void main()
{
iota(0, 10).map!(x => x *x).filter!(x => x % 2).writeln;
}
Re[9]: Facebook и язык D - первый шаг наверх.
От: jazzer Россия Skype: enerjazzer
Дата: 22.10.13 19:22
Оценка: +1
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>>По факту D Range нормально подходит только для SinglePass.


FR>Пока остальное отпущу.


FR>Но по этому у нас кажется сильное недопонимание, основной плюсs range это легкая

FR>комбинируемость функций с ними работающих и ленивость, все это по моему легко
FR>перекрывает недостатки.

FR>
FR>import std.stdio;
FR>import std.range;
FR>import std.algorithm;

FR>void main()
FR>{
FR>iota(0, 10).map!(x => x *x).filter!(x => x % 2).writeln;
FR>}
FR>


Одно другому (в смысле, диапазоны итераторам) не мешают.
Диапазоны хороши, когда надо по ним пройтись один раз и забыть. А итераторы хороши собственно для итерирования, которое может быть каким угодно хитрым. Но после итерирования берешь пару итераторов, заворачиваешь ее в диапазон и вперед — это, что делает boost::range, и твой пример элементарно на нем переписывается:
boost::copy( irange(0,10) | transformed(_1*_1) | filtered (_1%2)
           , std::ostream_iterator<int>(std::cout, "\n") )
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[9]: Facebook и язык D - первый шаг наверх.
От: Evgeny.Panasyuk Россия  
Дата: 22.10.13 19:22
Оценка:
Здравствуйте, FR, Вы писали:

FR>Но по этому у нас кажется сильное недопонимание, основной плюсs range это легкая

FR>комбинируемость функций с ними работающих и ленивость, все это по моему легко
FR>перекрывает недостатки.

Есть три сущности:
1. итераторы, как в STL
2. Range обвёртки над итераторами, как в Boost.Range или в Adobe ASL
3. D Range — в них нет никаких итераторов, есть только ranges

Комбинируемость есть и в 3 и в 2. А вот недостатки которые я выше перечислял — относятся только к 3.

FR>
FR>void main()
FR>{
FR>iota(0, 10).map!(x => x *x).filter!(x => x % 2).writeln;
FR>}
FR>


Пример комбинируемости range обвёрток над итераторами:
int main()
{
    for(auto x: irange(0, 10) | transformed( _1 * _1 ) | filtered(_1 % 2))
        cout << x << endl;
}

а внутри, всё те же итераторы.
И кстати, синтаксического оверхеда тут меньше чем в твоём примере
Re[12]: Facebook и язык D - первый шаг наверх.
От: FR  
Дата: 22.10.13 19:38
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>>>Для стандартных массивов перегрузки в библиотеке или в языке?

FR>>В языке.

EP>О чём и речь — что-то для range'ей уже встроено непосредственно в язык.


Нет там ничего для range обычная перегрузка операторов.
Массивы были в самой первой версии языка, в то время когда у Алекандреску с его rangeманией
была совсем другая любимая игрушка

FR>>Согласен, но в таких случаях часто ленивость спасает.


EP>У нас чистый permutation алгоритм — std::partition. В Phobos'е лишний раз дёргаются ручки у range'а, как тут поможет ленивость?


Тут возможно и нет.

FR>>По моему у тебя идея фикс "новые range бесплатно" ,


EP>Не только у меня — смотри выше что пишет A.A. про std::find — чтобы получить первую часть, нужно делать реализовывать новый тип range — Until, в то время как в STL он действительно получается бесплатно: [first, find(first, last, x))


Думаю, пока как выкрутится
Пока как идея реализовать кроме range еще и zipper думаю поиск и многое другое он вполне закроет.
Re[13]: Facebook и язык D - первый шаг наверх.
От: Evgeny.Panasyuk Россия  
Дата: 22.10.13 19:57
Оценка:
Здравствуйте, FR, Вы писали:

EP>>>>Для стандартных массивов перегрузки в библиотеке или в языке?

FR>>>В языке.
EP>>О чём и речь — что-то для range'ей уже встроено непосредственно в язык.
FR>Нет там ничего для range обычная перегрузка операторов.
FR>Массивы были в самой первой версии языка,

То что они были это понятно, речь о том что их адаптировали к range.

FR>в то время когда у Алекандреску с его rangeманией была совсем другая любимая игрушка


Какая?

FR>>>По моему у тебя идея фикс "новые range бесплатно" ,

EP>>Не только у меня — смотри выше что пишет A.A. про std::find — чтобы получить первую часть, нужно делать реализовывать новый тип range — Until, в то время как в STL он действительно получается бесплатно: [first, find(first, last, x))
FR>Думаю, пока как выкрутится

Пока думаешь, можешь любоваться на:
template<typename I, typename T>
I find(I first, I last, const T& x)
{
    while(first != last && *first != x)
        ++first;
    return first;
}
Re[14]: Facebook и язык D - первый шаг наверх.
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 23.10.13 05:47
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>>>Не только у меня — смотри выше что пишет A.A. про std::find — чтобы получить первую часть, нужно делать реализовывать новый тип range — Until, в то время как в STL он действительно получается бесплатно: [first, find(first, last, x))

FR>>Думаю, пока как выкрутится

EP>Пока думаешь, можешь любоваться на


EP>
EP>template<typename I, typename T>
EP>I find(I first, I last, const T& x)
EP>{
EP>    while(first != last && *first != x)
EP>        ++first;
EP>    return first;
EP>}
EP>


Свой тип не нужен, нужные типы генерятся сами при использовании комбинаторов из стандартной библиотеки.
auto firstPart(R,T)(R xs, T x)
{
    auto n = xs.save.countUntil(x);
    if (n < 0) return xs;
    return xs.takeExactly(n);
}

Те же три строчки, та же сложность, меньше мест для ошибки.
(и нет, тут нет двухкратного прохода)
Re[10]: Facebook и язык D - первый шаг наверх.
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 23.10.13 06:00
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

DM>>Но не только это, а выполнение почти произвольного кода. Прочитать файл, отсортировать, распарсить, посчитать...

EP>Это действительно круто(так же круто как и mixins), но эта фича слабо связанна с концепциям

Потому что концепции — слабое решение более общей проблемы — компайл-тайм проверки входных параметров на нужные свойства и выбор действий в зависимости от этого. Так вот, подобные проверки в D всегда будут мощнее плюсовых за счет встроенного интерпретатора.

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

EP>В каком виде? В смысле только SFINAE-like или, допустим, можно поймать static_assert где-то в глубине call-stack'а?

Можно в любом месте кода написать что-нибудь подобное:
static if (__traits(compiles, x + 1))
    writeln("number");
else
    writeln("owl");

Где вместо "х + 1" может быть любое выражение.

EP>4. Какой тест позволит различить InputIterator и ForwardIterator?


В стандартной либе есть предикаты вроде isForwardRange, внутри там обычный hasMember, т.к. подобные штуки имеют разные наборы функций.
Re[11]: Facebook и язык D - первый шаг наверх.
От: jazzer Россия Skype: enerjazzer
Дата: 23.10.13 07:01
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>Здравствуйте, Evgeny.Panasyuk, Вы писали:


DM>>>Но не только это, а выполнение почти произвольного кода. Прочитать файл, отсортировать, распарсить, посчитать...

EP>>Это действительно круто(так же круто как и mixins), но эта фича слабо связанна с концепциям

DM>Потому что концепции — слабое решение более общей проблемы — компайл-тайм проверки входных параметров на нужные свойства и выбор действий в зависимости от этого. Так вот, подобные проверки в D всегда будут мощнее плюсовых за счет встроенного интерпретатора.


Концепции — это не только проверки, это еще и type classes из Haskell. Плюс соответствующие перегрузки/специализации. Ты не офигеешь все это явно кодить на D-шном интерпретаторе?


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

EP>>В каком виде? В смысле только SFINAE-like или, допустим, можно поймать static_assert где-то в глубине call-stack'а?

DM>Можно в любом месте кода написать что-нибудь подобное:

DM>
DM>static if (__traits(compiles, x + 1))
DM>    writeln("number");
DM>else
DM>    writeln("owl");    
DM>

DM>Где вместо "х + 1" может быть любое выражение.

в С++11 есть SFINAE for expressions — практически то же самое, что __traits(compiles).
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[14]: Facebook и язык D - первый шаг наверх.
От: FR  
Дата: 23.10.13 07:05
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

FR>>Массивы были в самой первой версии языка,


EP>То что они были это понятно, речь о том что их адаптировали к range.


В языке не адаптировали, в языке только массивы и срезы, вся адаптация для range в
std::array похоже я тебя просто недопонял и говорил именно про операцию индексации и
среза. Вот пример:

import std.stdio;
import std.array;

int count(Range)(Range r)
{
int result = 0;
for(; !r.empty; r.popFront())
    ++result;
return result;
}

void main()
{
writeln(count([1, 2, 3]));
}


если закомментировать import std.array; то будет такая ошибка компиляции:

count000.d(7): Error: no property 'empty' for type 'int[]'
count000.d(7): Error: no property 'popFront' for type 'int[]'
count000.d(14): Error: template instance count000.count!(int[]) error instantiating



FR>>в то время когда у Алекандреску с его rangeманией была совсем другая любимая игрушка


EP>Какая?


Ну "вот и выросло поколение" С++ конечно, как раз наверно писал свое "Современное проектирование на C++".

FR>>Думаю, пока как выкрутится


EP>Пока думаешь, можешь любоваться на:

EP>
EP>template<typename I, typename T>
EP>I find(I first, I last, const T& x)
EP>{
EP>    while(first != last && *first != x)
EP>        ++first;
EP>    return first;
EP>}
EP>


Если не нужна голова с рангами также:

Range find(Range, T)(Range r, T t)
{
while(!r.empty && r.front != t)
    r.popFront();
return r;
}


А вообще я уже хотел идти искать белый флаг и приготовился начать писать
итераторы на D, но что-то нашептывало что где-то ошибка в рассуждениях.

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

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

Идем дальше forward iterator и forward range. Тут мы всегда можем комбинировать
пару итераторов и легко получить и голову и хвост. Но это же означает что мы всегда
можем дешево сохранять состояние forward range, и действительно в D это обязательное
требование (и такой интервал должен иметь член save), следовательно все возражения о дорогих
копиях интервалов и их дорогих прокрутках отметаются, все очень дешево.
Для bidirectional справедливо все тоже что и для forward.
Для random_access все вообще полностью бесплатно, доступны длина и индекс.

В сухом остатке получается что единственно некоторые алгоритмы запишутся с интервалами
менее красиво чем с итераторами, но тут рулит то что интервалы очень легко комбинируются в
отличии от итераторов и на примере того же find выше
Автор: D. Mon
Дата: 23.10.13
это уже показали.
Re[12]: Facebook и язык D - первый шаг наверх.
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 23.10.13 07:24
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Концепции — это не только проверки, это еще и type classes из Haskell. Плюс соответствующие перегрузки/специализации. Ты не офигеешь все это явно кодить на D-шном интерпретаторе?


А чего там кодить?
void test(R)(R xs) if (isRandomAccessRange!R)
{...}

void test(R)(R xs) if (isForwardRange!R)
{...}

Тайпклассы, перегрузки, вот они.

J>в С++11 есть SFINAE for expressions — практически то же самое, что __traits(compiles).


Но только снаружи функции? Посреди метода я могу сделать несколько таких вложенных проверок?
Re[6]: Facebook и язык D - первый шаг наверх.
От: DarkEld3r  
Дата: 23.10.13 07:28
Оценка:
Здравствуйте, matumba, Вы писали:

M>Вся надежда на D+LLVM.

И тебя не смущает, что LLVM на С++ написана? Как же можно на "говнокод на говноязыке" полагаться? Нее, надо срочно переписывать на D, а до этого ни за какие проекты браться ни в коем случае нельзя.
Re[13]: Facebook и язык D - первый шаг наверх.
От: jazzer Россия Skype: enerjazzer
Дата: 23.10.13 07:31
Оценка:
Здравствуйте, D. Mon, Вы писали:

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


J>>Концепции — это не только проверки, это еще и type classes из Haskell. Плюс соответствующие перегрузки/специализации. Ты не офигеешь все это явно кодить на D-шном интерпретаторе?


DM>А чего там кодить?

DM>
DM>void test(R)(R xs) if (isRandomAccessRange!R)
DM>{...}

DM>void test(R)(R xs) if (isForwardRange!R)
DM>{...}
DM>

DM>Тайпклассы, перегрузки, вот они.
а тут не будет неоднозначности?

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

J>>в С++11 есть SFINAE for expressions — практически то же самое, что __traits(compiles).


DM>Но только снаружи функции? Посреди метода я могу сделать несколько таких вложенных проверок?


Не, SFINAE только снаружи
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[14]: Facebook и язык D - первый шаг наверх.
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 23.10.13 08:06
Оценка: +1
Здравствуйте, jazzer, Вы писали:

DM>>Тайпклассы, перегрузки, вот они.

J>а тут не будет неоднозначности?

Может быть. Сейчас освежил в памяти детали. Короче, сначала констрейнты отсекают неподходящие варианты, а потом специализация выбирает самый подходящий. Если все еще есть неоднозначность, выдается ошибка. Поэтому на практике популярен подход со static if, там в явном виде логика выбора нужного варианта задается.
Re[15]: Facebook и язык D - первый шаг наверх.
От: Evgeny.Panasyuk Россия  
Дата: 23.10.13 11:38
Оценка:
Здравствуйте, D. Mon, Вы писали:

EP>>Пока думаешь, можешь любоваться на

EP>>
EP>>template<typename I, typename T>
EP>>I find(I first, I last, const T& x)
EP>>{
EP>>    while(first != last && *first != x)
EP>>        ++first;
EP>>    return first;
EP>>}
EP>>

DM>Свой тип не нужен, нужные типы генерятся сами при использовании комбинаторов из стандартной библиотеки.
DM>
DM>auto firstPart(R,T)(R xs, T x)
DM>{
DM>    auto n = xs.save.countUntil(x);
DM>    if (n < 0) return xs;
DM>    return xs.takeExactly(n);
DM>}
DM>

DM>Те же три строчки, та же сложность, меньше мест для ошибки.
DM>(и нет, тут нет двухкратного прохода)

1. Если звать стандартную библиотеку на помощь, то почему бы не взять сразу Until Речь то идёт об реализации. Код find выше — полностью self-contained.
2. find работает и для single pass range, а твой .save есть только начиная с forward — так?
3. Во время поиска у тебя передёргиваются и popFront и n, в find только итератор — оверхед по вычислениям
4. У тебя в результате будет и range и n, а в find только один итератор — то есть получается оверхед по памяти.
5. Это n, по сути является разжалованным итератором. Точно также, как я показывал выше, в Phobos'е, для алгоритмов по RandomAccess используются обычные целые, которые не знают откуда они пришли, и по сути те же итераторы, только менее удобные и безопасные.
6. В STL есть так называемые Counted Range — они определяются итератором и количеством элементов. Ты как раз попытался изобразить этот CountedRange, только менее эффективно.
7. find даёт два range'а, бесплатно, а у тебя только один. Например:
auto it = find(first, last, x);
process_first_half(first, it);
process_second_half(it, last);

8. У тебя возвращается либо один тип range (исходный), либо другой (то что вернёт takeExactly) — какой в итоге тип у твоего firstPart?
Re[15]: Facebook и язык D - первый шаг наверх.
От: Evgeny.Panasyuk Россия  
Дата: 23.10.13 12:00
Оценка:
Здравствуйте, FR, Вы писали:

FR>если закомментировать import std.array; то будет такая ошибка компиляции:

FR>
FR>count000.d(7): Error: no property 'empty' for type 'int[]'
FR>count000.d(7): Error: no property 'popFront' for type 'int[]'
FR>count000.d(14): Error: template instance count000.count!(int[]) error instantiating
FR>


ок, спасибо за информацию.

FR>>>в то время когда у Алекандреску с его rangeманией была совсем другая любимая игрушка

EP>>Какая?
FR>Ну "вот и выросло поколение" С++ конечно, как раз наверно писал свое "Современное проектирование на C++".

Я думал ты про D А эту книжку он лет за 8 перед range'ами написал.

FR>Если не нужна голова с рангами также:

FR>
FR>Range find(Range, T)(Range r, T t)
FR>{
FR>while(!r.empty && r.front != t)
FR>    r.popFront();
FR>return r;
FR>}
FR>


Как не нужна — конечно нужна, A.A. ведь как раз про голову и говорил.

FR>А вообще я уже хотел идти искать белый флаг и приготовился начать писать итераторы на D,


Хорошая идея

FR>но что-то нашептывало что где-то ошибка в рассуждениях.


Гони эти мысли, нет тут ошибки

FR>В общем все просто мы тут пытаемся скопом сравнивать любые итераторы и так как-будто

FR>для любых из них все плюсы имеют место.
FR>А надо все-таки смотреть на их типы.

FR>Берем простейший input iterator и соответственно input range. Для них описываемый

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

Я как раз выше и говорил, что D ranges для single pass ещё ничего:

EP>По факту D Range нормально подходит только для SinglePass.


FR>Идем дальше forward iterator и forward range. Тут мы всегда можем комбинировать

FR>пару итераторов и легко получить и голову и хвост. Но это же означает что мы всегда
FR>можем дешево сохранять состояние forward range, и действительно в D это обязательное
FR>требование (и такой интервал должен иметь член save), следовательно все возражения о дорогих
FR>копиях интервалов и их дорогих прокрутках отметаются, все очень дешево.
FR>Для bidirectional справедливо все тоже что и для forward.
FR>Для random_access все вообще полностью бесплатно, доступны длина и индекс.

Какие копии? Напиши find, который работает для всего начиная с single pass, а для forward и выше позволяет бесплатно получить первую часть в придачу ко второй

Лишние прокрутки были и есть в bidirectional partition, цена этих лишних прокруток зависит от используемой реализации range. Где-то передёргивание может быть дорогим, где-то дешёвым. В версии с итераторами, этих прокруток нет, by design

FR>В сухом остатке получается что единственно некоторые алгоритмы запишутся с интервалами

FR>менее красиво чем с итераторами, но тут рулит то что интервалы очень легко комбинируются в
FR>отличии от итераторов

Я же не против range'ей в стиле Boost.Range — они действительно легко комбинируются:
irange(0, 10) | transformed( _1 * _1 ) | filtered(_1 % 2)

Но — из таких range всегда можно достать итераторы, и работать с ними, а вот из D-style range — нет.
То есть гибридное решение — итераторы + сахар в виде range вокруг них, вполне жизнеспособное.

FR>и на примере того же find выше
Автор: D. Mon
Дата: 23.10.13
это уже показали.


Этот ужас не идёт ни в какое сравнение с std::find
Re[11]: Facebook и язык D - первый шаг наверх.
От: Evgeny.Panasyuk Россия  
Дата: 23.10.13 12:13
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>>>Но не только это, а выполнение почти произвольного кода. Прочитать файл, отсортировать, распарсить, посчитать...

EP>>Это действительно круто(так же круто как и mixins), но эта фича слабо связанна с концепциям
DM>Потому что концепции — слабое решение более общей проблемы — компайл-тайм проверки входных параметров на нужные свойства и выбор действий в зависимости от этого. Так вот, подобные проверки в D всегда будут мощнее плюсовых за счет встроенного интерпретатора.

Более мощные проверки — это всё понятно, и действительно мощно. Но это всё не то, и скорее относятся к compile-time вычислениям в общем, чем к концепциям.
Концепции выберут нужную перегрузку, а static if из твоего примера:
void test(R)(R xs) if (isRandomAccessRange!R)
{...}

void test(R)(R xs) if (isForwardRange!R)
{...}
сфейлится


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

EP>>В каком виде? В смысле только SFINAE-like или, допустим, можно поймать static_assert где-то в глубине call-stack'а?
DM>Можно в любом месте кода написать что-нибудь подобное:
DM>
DM>static if (__traits(compiles, x + 1))
DM>    writeln("number");
DM>else
DM>    writeln("owl");    
DM>

DM>Где вместо "х + 1" может быть любое выражение.

Это как раз SFINAE-like.
А мне интересно, можно ли поймать такое:
static if (__traits(compiles, some_function_with_static_assert_inside() ))
// ..


EP>>4. Какой тест позволит различить InputIterator и ForwardIterator?

DM>В стандартной либе есть предикаты вроде isForwardRange, внутри там обычный hasMember, т.к. подобные штуки имеют разные наборы функций.

В STL их тоже можно различить, но речь не об этом, а о том, что далеко не все свойства можно протестировать.
Re[16]: Facebook и язык D - первый шаг наверх.
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 23.10.13 12:27
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>1. Если звать стандартную библиотеку на помощь, то почему бы не взять сразу Until Речь то идёт об реализации. Код find выше — полностью self-contained.


В библиотеке уже есть findSplit, findSplitAfter и findSplitBefore, первый как раз дает два рэнджа, два других — левую и правую часть. Но они ищут не один элемент, а сразу "подстроку", поэтому их приводить я не стал.

EP>2. find работает и для single pass range, а твой .save есть только начиная с forward — так?


Так. Возврат левой части (от начала до найденного элемента) для не forward рэнджа смысла не имеет, элементы уже однажды прочитаны. D такую попытку здесь пресекает. А плюсы? Спокойно вернут итератор на протухшие данные?

EP>3. Во время поиска у тебя передёргиваются и popFront и n, в find только итератор — оверхед по вычислениям


Ага, на один инкремент целого. Что на порядок быстрее, чем чтение байта из ближайшего кэша даже. Т.е. реально не оверхэд абсолютно, спасибо instruction level parallelism.

EP>4. У тебя в результате будет и range и n, а в find только один итератор — то есть получается оверхед по памяти.


Да, опять же на целое одно число. Мы собираемся зачем-то хранить мильоны итераторов/рэнджей? На практике их обычно в один момент до нескольких штук используется, и те на стеке.

EP>5. Это n, по сути является разжалованным итератором. Точно также, как я показывал выше, в Phobos'е, для алгоритмов по RandomAccess используются обычные целые, которые не знают откуда они пришли, и по сути те же итераторы, только менее удобные и безопасные.


А какая есть безопасная альтернатива для Random access?

EP>6. В STL есть так называемые Counted Range — они определяются итератором и количеством элементов. Ты как раз попытался изобразить этот CountedRange, только менее эффективно.


Почему менее?

EP>7. find даёт два range'а, бесплатно, а у тебя только один.


Мне только он и нужен был. Вернуть вместо xs tuple(xs, ys) (где ys — сохраненный двумя строчками выше xs.save) много ума не нужно.

EP>8. У тебя возвращается либо один тип range (исходный), либо другой (то что вернёт takeExactly) — какой в итоге тип у твоего firstPart?


Хороший вопрос. Почему-то компилятор в нем разобрался без моей помощи.
Re[8]: Facebook и язык D - первый шаг наверх.
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 23.10.13 12:27
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

FR>>Ну реально же страшно по сравнению с D.


EP>
EP>foreach(x; tuple_like)
EP>{
EP>    // ...
EP>}
EP>//versus
EP>for_each(tuple_like, [&](auto x)
EP>{
EP>    // ...
EP>});
EP>

EP>Имхо, ничего страшного

Давай проверим

foreach(x; tuple_like)
{
    if( ля )
      continue;
    if( ля ля)
      break;
    if( ля ля ля)
      return;
}


Покажи аналог ?

FR>>И не дай бог мелкую ошибку допустить и получим километровое сообщение,

EP>Против километровых ошибок помогут концепции.

Концепции уже для того, нужны что бы просто из функции выйти.
Re[12]: Facebook и язык D - первый шаг наверх.
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 23.10.13 12:40
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

DM>>static if (__traits(compiles, x + 1))

DM>>Где вместо "х + 1" может быть любое выражение.

EP>Это как раз SFINAE-like.


Я не вижу сходства. Выше уже сказали, что SFINAE нельзя использовать внутри функций, в отличие от static if.

EP>А мне интересно, можно ли поймать такое:

EP>
EP>static if (__traits(compiles, some_function_with_static_assert_inside() ))
EP>// ..
EP>


Да, может. Хоть static assert, хоть динамическая проверка.
Такой пример только что запустил:
bool something(T)(T x)
{
    static assert(is(T==bool));
    return true;
}

void main(string[] argv)
{
    static if (__traits(compiles, something(2+3)))
        writeln("yes");
    else 
        writeln("no");
}

Работает как со static if, так и просто в виде булевого значения.
Re[17]: Facebook и язык D - первый шаг наверх.
От: Evgeny.Panasyuk Россия  
Дата: 23.10.13 13:11
Оценка:
Здравствуйте, D. Mon, Вы писали:


EP>>1. Если звать стандартную библиотеку на помощь, то почему бы не взять сразу Until Речь то идёт об реализации. Код find выше — полностью self-contained.


DM>В библиотеке уже есть findSplit, findSplitAfter и findSplitBefore, первый как раз дает два рэнджа, два других — левую и правую часть.


findSplit вообще возвращает три range, а нужны [first, find(first, last)) и [find(first, last), last), или например тоже самое с partition.

EP>>2. find работает и для single pass range, а твой .save есть только начиная с forward — так?

DM>Так. Возврат левой части (от начала до найденного элемента) для не forward рэнджа смысла не имеет, элементы уже однажды прочитаны. D такую попытку здесь пресекает. А плюсы? Спокойно вернут итератор на протухшие данные?

Покажи реализацию аналога std::find.

EP>>3. Во время поиска у тебя передёргиваются и popFront и n, в find только итератор — оверхед по вычислениям

DM>Ага, на один инкремент целого. Что на порядок быстрее, чем чтение байта из ближайшего кэша даже. Т.е. реально не оверхэд абсолютно, спасибо instruction level parallelism.

Не один инкремент, а на каждой итерации. И не instruction level parallelism, а overhead by design, чего тут спорить

EP>>4. У тебя в результате будет и range и n, а в find только один итератор — то есть получается оверхед по памяти.

DM>Да, опять же на целое одно число. Мы собираемся зачем-то хранить мильоны итераторов/рэнджей? На практике их обычно в один момент до нескольких штук используется, и те на стеке.

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

EP>>5. Это n, по сути является разжалованным итератором. Точно также, как я показывал выше, в Phobos'е, для алгоритмов по RandomAccess используются обычные целые, которые не знают откуда они пришли, и по сути те же итераторы, только менее удобные и безопасные.

DM>А какая есть безопасная альтернатива для Random access?

В смысле? Вот ты реализуешь некий алгоритм который использует несколько random access range'ей — дёргаешь индексы туда-сюда, при использовании D Range нужно ещё не перепутать из какого range какой индекс, в том время как из самого итератора можно и читать/писать.

EP>>6. В STL есть так называемые Counted Range — они определяются итератором и количеством элементов. Ты как раз попытался изобразить этот CountedRange, только менее эффективно.

DM>Почему менее?

Лишние операции, лишняя память.

EP>>7. find даёт два range'а, бесплатно, а у тебя только один.

DM>Мне только он и нужен был. Вернуть вместо xs tuple(xs, ys) (где ys — сохраненный двумя строчками выше xs.save) много ума не нужно.

Ну так покажи полную реализацию аналога find, если всё так просто

EP>>8. У тебя возвращается либо один тип range (исходный), либо другой (то что вернёт takeExactly) — какой в итоге тип у твоего firstPart?

DM>Хороший вопрос. Почему-то компилятор в нем разобрался без моей помощи.

Как именно? Какой typeof у результата?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.