Здравствуйте, Dmi3S, Вы писали:
DS>Здравствуйте, jazzer, Вы писали:
DS>>>Что нового привносит данная концепция? J>>Имхо — ничего, если принимать во внимание существование Boost.Range. DS>Навскидку. DS>
DS>More composition opportunities
DS>• Stride: span a range several steps at once
DS>Iterators can’t implement it!
Stride — это когда advance(1) эквивалентен advance(n)?
И почему же итераторы этого не могут?
не, многие операции над последовательностями (т.е. превращения одних последовательностей в другие) делаются легче и прямее, когда они описаны в терминах последовательностей, тут никто не спорит (хотя тоже с оговорками — некоторые превращения могут включать в себя нетривиальное итерирование).
Но это же не повод свести к последовательностям вообще всё, начиная с итераторов.
Это все равно что сказать, что на классах круче и удобнее писать, поэтому давайте забаним фундаментальные типы (int, double...).
Здравствуйте, jazzer, Вы писали:
J>Stride — это когда advance(1) эквивалентен advance(n)? J>И почему же итераторы этого не могут?
Я так понял, что фишка в том, что сделав advance(n) на random-access итератор можно выскочить за end(). Соответственно, безопасный способ это n*(advance(1)+if(!end)). А в range, вроде как, это можно сделать эффективнее.
Re[13]: BoostCon - Alexandrescu - Iterators Must Go (video)
Здравствуйте, jazzer, Вы писали:
J>не, многие операции над последовательностями (т.е. превращения одних последовательностей в другие) делаются легче и прямее, когда они описаны в терминах последовательностей, тут никто не спорит (хотя тоже с оговорками — некоторые превращения могут включать в себя нетривиальное итерирование). J>Но это же не повод свести к последовательностям вообще всё, начиная с итераторов.
Я так понимаю, что выжить должен только один. Ни кто не пойдет на удвоение заголовков функций, которые будут работать как с ranges, так и с итераторами. Соответственно, в этом ключе Александреску и сделал свой доклад. То, что для большинства алгоритмов больше подходят последовательности, как бы очевидно. Но вот что при таком раскладе делать пользователям — не понятно совершенно. Не тяжело, конечно, прочитать 10-15 страниц по LISP, и сделать выводы. Тяжело сознательно идти на потери памяти/данных/читаемости ради красоты. Да еще и не иметь выбора. И что тут предложить, я не знаю. Опять же, в LISP список (т.е. то, на что range) считается неизменным. Невозможна ситуация, когда кто-то втихую сказал контейнеру clear(). В плюсах же...
Если интересует мое личное мнение, то пока что ranges не кажутся мне жизнеспособной альтернативой. Но тенденция радует, да
J>Это все равно что сказать, что на классах круче и удобнее писать, поэтому давайте забаним фундаментальные типы (int, double...).
И вывести эти классы из System.ValueType
PS. Некорректное сравнение, я знаю. Но удержаться не смог.
Re[13]: BoostCon - Alexandrescu - Iterators Must Go (video)
Здравствуйте, Dmi3S, Вы писали:
DS>Здравствуйте, jazzer, Вы писали:
J>>Stride — это когда advance(1) эквивалентен advance(n)? J>>И почему же итераторы этого не могут?
DS>Я так понял, что фишка в том, что сделав advance(n) на random-access итератор можно выскочить за end(). Соответственно, безопасный способ это n*(advance(1)+if(!end)). А в range, вроде как, это можно сделать эффективнее.
Для random-access-итератора это будет просто advance( min(n,distance(i,end)) ).
цикл, соответственно, будет не while(++i != end), а while(advance( min(n,distance(i,end)) ) != end) — имхо, не принципиальное усложнение.
end тут сидит в любом случае, потому что в любом случае тебе нужно условие окончания цикла.
Здравствуйте, Dmi3S, Вы писали:
DS>Здравствуйте, jazzer, Вы писали:
J>>не, многие операции над последовательностями (т.е. превращения одних последовательностей в другие) делаются легче и прямее, когда они описаны в терминах последовательностей, тут никто не спорит (хотя тоже с оговорками — некоторые превращения могут включать в себя нетривиальное итерирование). J>>Но это же не повод свести к последовательностям вообще всё, начиная с итераторов.
DS>Я так понимаю, что выжить должен только один. Ни кто не пойдет на удвоение заголовков функций, которые будут работать как с ranges, так и с итераторами. Соответственно, в этом ключе Александреску и сделал свой доклад.
Ну, я лично не вижу в этом радикальной проблемы.
Вон, Adobe с ASL фактически продублировали интерфейс СТЛ, и ничего, вроде, живут..
Хотя, по совести говоря, я голыми алгоритмами из STL и не пользуюсь практически, все время ASL, а зачастую и Boost.Foreach, когда нужно тупо пройтись по всему контейнеру/диапазону и что-то сделать, а функтор писать смысла нету (и такое бывает часто, естественно).
DS>То, что для большинства алгоритмов больше подходят последовательности, как бы очевидно. Но вот что при таком раскладе делать пользователям — не понятно совершенно. Не тяжело, конечно, прочитать 10-15 страниц по LISP, и сделать выводы. Тяжело сознательно идти на потери памяти/данных/читаемости ради красоты. Да еще и не иметь выбора. И что тут предложить, я не знаю.
Я вижу гибридный подход.
Диапазоны — диапазонами, и мы должны, безусловно, иметь полный набор операций над ними, но и итераторы никуда не денутся, чтобы ходить по тем же диапазонам.
DS>Опять же, в LISP список (т.е. то, на что range) считается неизменным. Невозможна ситуация, когда кто-то втихую сказал контейнеру clear(). В плюсах же...
Ну это уже из другой оперы вопрос, и он одинаково применим как к итераторам, так и к диапазонам.
DS>Если интересует мое личное мнение, то пока что ranges не кажутся мне жизнеспособной альтернативой. Но тенденция радует, да
Ну, мое имхо, что если не заниматься джихадом, то ranges отлично будут жить, потому что они фактически играют роль итераторов на стероидах.
Но я вот не поверю, что реализация какой-нть хитрой итерации на диапазонах порулит по скорости и памяти итерацию на голых итераторах, если не сказать — указателях.
В общем, диапазоны — вещь хорошая и удобная, и я уже давно ими пользуюсь в виде Adobe.ASL (которая внутри себя дергает просто Boost.Range) — код становится гораздо чище. Но в некоторых ситуациях от итераторов (ну или позиций в диапазоне, что, по сути, тоже является итератором) никуда, разве что ценой кривого и неудобного кода.
J>>Это все равно что сказать, что на классах круче и удобнее писать, поэтому давайте забаним фундаментальные типы (int, double...). DS>И вывести эти классы из System.ValueType
Ага, именно на это я и намекал. Еще надо искоренить все свободные функции, тоже сделать их классами — и ведь даже языки такие есть.... Которые теперь изворачиваются через всякие костыли в виде анонимных классов...
You will always get what you always got
If you always do what you always did
Re: BoostCon - Alexandrescu - Iterators Must Go (video)
От:
Аноним
Дата:
05.08.09 16:35
Оценка:
Меня вообще все это удивляет, ей-богу.
Есть же куда более простое, интуитивное и эффективное решение (уже давно известное в других языках): чтобы итератор сам знал — валиден он или нет.
При таком подходе и диапазоны легко сделать: диапазон просто будет частным случаем итератора.
Но при этом итератор по односвязному списку, например, диапазоном не будет: это будет вообще один указатель, а у Александреску все равно придется делать два указателя, даже если это не нужно.
У Александреску если нужно указать один элемент, нужен будет вырожденный диапазон, а это будет не то, чтобы даже часто, а просто постоянно.
Крайне глупой мне представляется итерация по списку с помощью вырожденного диапазона, указывающего на один элемент.
Это, кстати, нарушение знаменитого принципа "не платить за то, что не используешь".
Re[14]: BoostCon - Alexandrescu - Iterators Must Go (video)
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Dmi3S, Вы писали:
DS>>Здравствуйте, jazzer, Вы писали:
J>Для random-access-итератора это будет просто advance( min(n,distance(i,end)) ). J>цикл, соответственно, будет не while(++i != end), а while(advance( min(n,distance(i,end)) ) != end) — имхо, не принципиальное усложнение. J>end тут сидит в любом случае, потому что в любом случае тебе нужно условие окончания цикла.
Я начинаю понимать, что же я не понимал раньше
Скажем, есть алгоритм сортировки sort, работающий с range. Есть некий вектор. Задача состоит в том, чтобы расставить в порядке возрастания все элементы, стоящие на позициях кратных 13. Решение будет выглядеть примерно так:
vector vec;
// fill vec ...
sort( stride(vec,13) );
Конечно, тут можно вспомнить о boost::counting_iterator, и сказать, что эта функциональность, пусть и не в таком сахарном виде, уже есть. В ответ можно предположить, что нам потребовался еще и каждый 19й элемент:
vector vec;
// fill vec ...
sort( chain(stride(vec,13),stride(vec,19)) );
Конечно, пример искусственен. Но он мне нравится, и возможность использования range в таком стиле -- несомненный плюс имхо.
Re[2]: BoostCon - Alexandrescu - Iterators Must Go (video)
Здравствуйте, Аноним, Вы писали:
А>Крайне глупой мне представляется итерация по списку с помощью вырожденного диапазона, указывающего на один элемент.
Re[5]: BoostCon - Alexandrescu - Iterators Must Go (video)
От:
Аноним
Дата:
05.08.09 19:20
Оценка:
Крайне глупой мне представляется итерация по списку с помощью вырожденного диапазона, указывающего на один элемент [там, где для этого нет никакой необходимости].
(Это пояснение для тех, кто в танке, потому что из контекста это и так прекрасно должно быть понятно.)
Re[5]: BoostCon - Alexandrescu - Iterators Must Go (video)
От:
Аноним
Дата:
05.08.09 19:26
Оценка:
А>>Крайне глупой мне представляется итерация по списку с помощью вырожденного диапазона, указывающего на один элемент.
Да и потом, это к чему? У меня в примере кода нет никакого вырожденного диапазона.
Re[6]: BoostCon - Alexandrescu - Iterators Must Go (video)
Здравствуйте, Аноним, Вы писали:
А>>>Крайне глупой мне представляется итерация по списку с помощью вырожденного диапазона, указывающего на один элемент.
А>Да и потом, это к чему? У меня в примере кода нет никакого вырожденного диапазона.
Т.е. этим итератором даже по списку пройтись нельзя?
Re[7]: BoostCon - Alexandrescu - Iterators Must Go (video)
От:
Аноним
Дата:
05.08.09 19:35
Оценка:
DS>Т.е. этим итератором даже по списку пройтись нельзя?
Не понял, вы код читали? Он же элементарен.
Итератор хранит указатель на конец диапазона и, таким образом, позволяет выполнить алгоритм, производящий итерацию на диапазоне произвольного множества, у которого есть однонаправленный итератор.
Избыточность в этом случае равна нулю, то есть лишних данных нигде не хранится и не передается (если только не учитывать специфику конкретного контейнера).
Вырожденных диапазонов тоже нет («вырожденным» я в данном случае называю диапазон, который содержит лишь один элемент).
Re[8]: BoostCon - Alexandrescu - Iterators Must Go (video)
Здравствуйте, Аноним, Вы писали:
DS>>Т.е. этим итератором даже по списку пройтись нельзя?
А>Не понял, вы код читали? Он же элементарен.
Да, читал.
А>Итератор хранит указатель на конец диапазона и, таким образом, позволяет выполнить алгоритм, производящий итерацию на диапазоне произвольного множества, у которого есть однонаправленный итератор.
Кэп, не узнал вас.
А>Избыточность в этом случае равна нулю, то есть лишних данных нигде не хранится и не передается (если только не учитывать специфику конкретного контейнера).
А>Вырожденных диапазонов тоже нет («вырожденным» я в данном случае называю диапазон, который содержит лишь один элемент).
Ок, вопросы для самопроверки.
Как мне воспользоваться этим итератором для того, чтобы указать на int [10]? // это к слову, но ведь иногда приходится.
Как этим итератором указать на один элемент?
Если мысленно выкинуть из кода непрозрачную IsValid(), typedef и сделать
s/ForwardRangeIterator/range
s/MoveNext/popFront
s/GetCurrent/front
, то полученный результат ни чего не напомнит?
Почему конструкция, семантически эквивалентная range, который инкапсулирует работу со списком итераторов, называется Bla_bla_bla_Iterator?
Что такое range?
Что такое итератор?
В чем разница между ними?
Почему использовать частный случай range "список указателей с одним элементом" противоестественно?
Почему использовать <неразборчиво> случай "iterator (указатель на один элемент) является списком" естественно?
Как обсуждать эти концепции с человеком, у которого граница между списком указателей и указателем на один элемент проходит не там же, где и у вас?
А если эта граница плавает в пределах одного предложения?
Доп. вопрос.
Как может быть реализована функция IsValid() в каком-либо из возможных BaseIterator? (ключевое слово observer)
Прим.
Ответ на доп вопрос IsValid() { return true; } уже получен от КО.
Re[9]: BoostCon - Alexandrescu - Iterators Must Go (video)
Здравствуйте, Dmi3S, Вы писали:
DS>s/MoveNext/popFront DS>, то полученный результат ничего не напомнит?
С прямым итератором это действительно так.
А вот у двунаправленного итератора будет еще и MovePrev — ы? Аналогично для итератора с произвольным доступом.
Концепция "диапазоны можут только уменьшаться" выглядит довольно сильно ограничивающей, когда мы переходим к итерациям.