Re[10]: Зачем нужны итераторы?
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 12:49
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Ленивость в этом плане меняет всё. foreach может замениться, например, на простой вызов функции для обхода ленивой структуры. Специальная конструкция не нужна.


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

L>Кстати, а какой будет typeof у результата функции с yield-ами?


IEnumerable[X]
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Зачем нужны итераторы?
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 13:07
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Ленивость меняет то, что свертка сворачивает контейнер в "итератор" лениво.

K>
K>toList :: Foldable t => t a -> [a]
K>toList = foldr (:) []
K>

K>А в энергичном языке придется делать ленивую свертку, чтобы реализовать аналог Foldable — что сложнее.

Сложнее но вполне реализуемо.

Кстати, я не могу понять смысла в ленивом fold-е. Ведь если я использую fold, то в общем случае я хочу получить какое-то значение. И только если я получаю какой-то список, то имеет смысл в ленивости, а при получения, скажем, целого числа, что мне даст ленивость?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Зачем нужны итераторы?
От: Klapaucius  
Дата: 01.12.10 13:20
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Сложнее но вполне реализуемо.


Да, реализуемо.

VD>Кстати, я не могу понять смысла в ленивом fold-е. Ведь если я использую fold, то в общем случае я хочу получить какое-то значение. И только если я получаю какой-то список, то имеет смысл в ленивости,


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

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[11]: Зачем нужны итераторы?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 01.12.10 14:01
Оценка: +1 :)
Здравствуйте, VladD2, Вы писали:

L>>Ленивость в этом плане меняет всё. foreach может замениться, например, на простой вызов функции для обхода ленивой структуры. Специальная конструкция не нужна.

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

- Папа, это что?
— Море, море, море!
— Папа, а что это было?


Да и разговор зачем переводишь? Конкретно речь идёт о том, что в итераторах вообще и в конструкции foreach в частности нет необходимости в случае ленивости по умолчанию. Не согласен? Приведи пример, когда недостаточно ленивости.

L>>Кстати, а какой будет typeof у результата функции с yield-ами?

VD>IEnumerable[X]

Конкретный тип какой будет? Вот в python, например, generator. В Scala — такой же, как и внешний тип. А в C#?
Re[12]: Зачем нужны итераторы?
От: hardcase Пират http://nemerle.org
Дата: 01.12.10 14:04
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Конкретный тип какой будет? Вот в python, например, generator. В Scala — такой же, как и внешний тип. А в C#?


А в C# — System.Collections.Generic.IEnumerable<T>.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[12]: Зачем нужны итераторы?
От: Воронков Василий Россия  
Дата: 01.12.10 14:59
Оценка:
Здравствуйте, lomeo, Вы писали:

L>>>Кстати, а какой будет typeof у результата функции с yield-ами?

VD>>IEnumerable[X]
L>Конкретный тип какой будет? Вот в python, например, generator. В Scala — такой же, как и внешний тип. А в C#?

Там фишка в том, что компилятор генерирует для тебя реализацию интерфейса IEnumerable<>.
Re[4]: Зачем нужны итераторы?
От: Воронков Василий Россия  
Дата: 01.12.10 15:31
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Кстати, не все такой подход избрали. В F# для аналога генераторов используются Computation Expressions, то есть по сути CPS. В C# 5 появится sync/await. Реализация будет опять же на основе ДКА (точнее даже на основе итераторов). В F# и Nemerle есть аналогичная фича реализованная на базе Computation Expressions. Однако реализация на базе ДКА будет ничем не хуже. Так что возможно в немреле и ее реализуем.


В F# есть "yield!". Как он будет работать в варианте с ДКА?
Re[5]: Зачем нужны итераторы?
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 15:41
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>В F# есть "yield!". Как он будет работать в варианте с ДКА?


Описание того как sync/await сделаны в шарпе доступны в Интернете. Да поможет тебе гугль. Ну, а то что названия не совпадают, ты уже извини.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Зачем нужны итераторы?
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.12.10 15:54
Оценка:
L>Да и разговор зачем переводишь? Конкретно речь идёт о том, что в итераторах вообще и в конструкции foreach в частности нет необходимости в случае ленивости по умолчанию. Не согласен? Приведи пример, когда недостаточно ленивости.

приведи, пожалуйста, критерий недостаточности.
если брать определение недостаточности по тьюрингу, то даже ленивость не нужна, а достаточно из всего хаскелая 0, 1 и двунаправленного списка.
Re[15]: Зачем нужны итераторы?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 01.12.10 17:43
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Вот например (красный FoldLeft в строке 83). Автор этого шедевра этой жести — ваш покорный слуга. После 20 минутной медитации над FoldLeft-ом + RevMap-ом переписал на два foreach-а. Код стал понятнее и потом пережил еще пару рефакнторингов — это конвертер switch конструкции C# в match Nemerle. Иммутабельность это хорошо, когда без фанатизма.


FoldLeft — это вообще не свёртка (катаморфизм), а просто итерация.
Что касается кода, то я вижу, что в fold намешано сразу несколько вещей — группировка по условию, отображение группы на свёртку. Стоит разбить, должно получиться сильно проще.
Re[13]: Зачем нужны итераторы?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 01.12.10 17:48
Оценка:
Здравствуйте, DarkGray, Вы писали:

L>>Да и разговор зачем переводишь? Конкретно речь идёт о том, что в итераторах вообще и в конструкции foreach в частности нет необходимости в случае ленивости по умолчанию. Не согласен? Приведи пример, когда недостаточно ленивости.

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

О чём в этом треде вообще речь? Выразительность, наверное. Скажем, есть пример с итераторами, который выглядит выразительнее, чем схожее решение с использованием ленивости по умолчанию?
Re[13]: Зачем нужны итераторы?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 01.12.10 17:54
Оценка: +1
Здравствуйте, hardcase, Вы писали:

L>>Конкретный тип какой будет? Вот в python, например, generator. В Scala — такой же, как и внешний тип. А в C#?

H>А в C# — System.Collections.Generic.IEnumerable<T>.

Я совсем не знаю C#, но мне казалось, что конкретный объект должен иметь конкретный (пусть и сгенеренный, возможно, анонимный) тип, который реализует интерфейсы. Т.е. как бы это выглядело в Java — был бы сгенерен некий класс, имплементирующий интерфейс IEnumerable<T> и пользоваться его экземплярами мы могли бы только через этот интерфейс (ну ещё Object, но это неважно).

Я к чему этот разговор затеял — если это так и есть, как я предполагаю, то этот IEnumerable<T> мало чем от ленивого списка отличается. И все функции, возвращающие IEnumerable<T> аналогичны функциям, возвращающим [a] в ленивом языке. Маловато абстракции здесь по возвращаемому типу.
Re[13]: Зачем нужны итераторы?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 01.12.10 17:58
Оценка:
Здравствуйте, Воронков Василий, Вы писали:


ВВ>Там фишка в том, что компилятор генерирует для тебя реализацию интерфейса IEnumerable<>.


Угу, спасибо.
http://rsdn.ru/forum/philosophy/4061126.1.aspx
Автор: lomeo
Дата: 01.12.10
Re[14]: Зачем нужны итераторы?
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.12.10 19:15
Оценка:
L>Я совсем не знаю C#, но мне казалось, что конкретный объект должен иметь конкретный (пусть и сгенеренный, возможно, анонимный) тип, который реализует интерфейсы. Т.е. как бы это выглядело в Java — был бы сгенерен некий класс, имплементирующий интерфейс IEnumerable<T> и пользоваться его экземплярами мы могли бы только через этот интерфейс (ну ещё Object, но это неважно).

в C# всё не так:
есть только интерфейс IEnumerable<X>, и есть функция которая этот интерфейс возвращает, и больше ничего нет.

т.е. наверху сплошная функциональщина и никаких объектов
Re[15]: Зачем нужны итераторы?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 01.12.10 19:31
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>в C# всё не так:

DG>есть только интерфейс IEnumerable<X>, и есть функция которая этот интерфейс возвращает, и больше ничего нет.
DG>т.е. наверху сплошная функциональщина и никаких объектов

Хм. Плохо понимаю, но допустим. Тогда вопрос в силе — есть какая-то разница на уровне абстракций между функцией, возвращающей с помощью yield, IEnumerator<T> и функцией, возвращающей ленивый список?

И для самообразования. Я прочитал, что

When the compiler detects your iterator, it will automatically generate the Current, MoveNext and Dispose methods of the IEnumerator or IEnumerator<T> interface.

Таким образом, генерится заглушка, реализующая интерфейс. А вот тип этой заглушки при запросе GetType вернёт IEnumerator<T> — так сделано? Проверить, к сожалению, не могу, поэтому спрашиваю. Сомнения возникли из определения GetType:

Return Value The Type instance that represents the exact runtime type of the current instance.

Re[16]: Зачем нужны итераторы?
От: hardcase Пират http://nemerle.org
Дата: 01.12.10 19:50
Оценка:
Здравствуйте, lomeo, Вы писали:

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


DG>>в C# всё не так:

DG>>есть только интерфейс IEnumerable<X>, и есть функция которая этот интерфейс возвращает, и больше ничего нет.
DG>>т.е. наверху сплошная функциональщина и никаких объектов

L>Хм. Плохо понимаю, но допустим. Тогда вопрос в силе — есть какая-то разница на уровне абстракций между функцией, возвращающей с помощью yield, IEnumerator<T> и функцией, возвращающей ленивый список?


L>И для самообразования. Я прочитал, что

L>

L>When the compiler detects your iterator, it will automatically generate the Current, MoveNext and Dispose methods of the IEnumerator or IEnumerator<T> interface.


Тип заглушки будет таким, каким мы его объявили:
IEnumerable<int> Range(int start, int end)
{
  for(var i = start; i <= end; ++i)
    yield return i;
}
/* иЗвиНите зА неРовнЫй поЧерК */
Re[16]: Зачем нужны итераторы?
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.12.10 22:14
Оценка:
L>Хм. Плохо понимаю, но допустим. Тогда вопрос в силе — есть какая-то разница на уровне абстракций между функцией, возвращающей с помощью yield, IEnumerator<T> и функцией, возвращающей ленивый список?

в целом — нет. разница может быть только в мелких нюансах


L>И для самообразования. Я прочитал, что

L>

L>When the compiler detects your iterator, it will automatically generate the Current, MoveNext and Dispose methods of the IEnumerator or IEnumerator<T> interface.

L>Таким образом, генерится заглушка, реализующая интерфейс. А вот тип этой заглушки при запросе GetType вернёт IEnumerator<T> — так сделано?

там будет какое-нибудь страшное генеренное имя, ничего не говорящее. например: "<object>d__3<TResult, TItem>"
Re[3]: Зачем нужны итераторы?
От: Wolverrum Ниоткуда  
Дата: 02.12.10 01:36
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А я не удивлюсь если тебе замеят, что шаблон Посетитель и функция map решают разные задачи.


В любом случае map — частный случай fold с одной стороны, а с другой — "Visitors &mdash; Equational functions. Frequently foldable"
Так что абсолютно неправым я быть не могу
Re: Зачем нужны итераторы?
От: velkin Удмуртия http://blogs.rsdn.org/effective/
Дата: 05.02.12 23:53
Оценка: +1
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Т.е. итераторы просто сахар? Зачем они нужны?


Итератор является шаблоном проектирования. Как идея он не зависит от конкретной реализации в каком-либо языке, или в библиотеке алгоритмов. Нужен он:

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

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

типичный итератор:
a. установка на начало последовательности (возвращает итератор)
b. проверка на конец последовательности (возвращает конец или нет)
c. переход к следующему элементу последовательности (ничего не возвращает)
d. получить текущий элемент структуры (возвращает текущий элемент структуры на котором остановилась последовательность)

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

(d)получение текущего элемента + (c)переход на следующий элемент = получить следующий элемент

Получится тоже вполне себе итератор, только при использовании элемента более одного раза придётся куда-то записывать способ указания на сам элемент. В трансформации итератора можно пойти и дальше, получив то, что здесь было названо функцией замыкания. Его логика возможно потребует более сложного решения, чем take + 1, где take типа int. Иными словами как бы не меняли итератор, в итоге скорее всего получим менее удобный и более корявый итератор, чем тот, который уже стал классикой, но это будет тоже итератор. А иначе попросту лишимся возможностей пунктов 1 и 2.

P.S. Ещё существует потоковый итератор, обычно ему приписывают I/O, то есть ввод/вывод. Хотя идея схожая, с разницей, что данные поступают не элементами, а кусочками. Тоже своего рода понятие. Мышления на более высоких уровнях абстракции, цель которых не усложнить, а упростить жизнь разработчикам.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.