Здравствуйте, AndrewVK, Вы писали:
AVK>Так сколько раз?
Два
Товарищ, вы смешиваете напитки
TestEnum() выполняется, естественно, один раз. Он формирует набор элементов, по которому осуществляет проход наш ForEach — и это второй раз. Именно об этом я и говорил. Т.е. сначала проход по коллекции с целью выборки, затем проход по выборке с целью выполнения действия.
Что кстати в твоем примере и видно:
AVK>Action 2 AVK>2
А вот в случае с методом ForEach<T>(this IEnumerable<T> source, Action<T> action, Func<bool> condition) проход по коллекции будет вообще один.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>TestEnum() выполняется, естественно, один раз. Он формирует набор элементов, по которому осуществляет проход наш ForEach — и это второй раз.
Смешивает напитки тут кто то другой. Невозможно выполнить два прохода по данному итератору и не вызвать вывод на консоль. В принципе.
ВВ> Именно об этом я и говорил. Т.е. сначала проход по коллекции с целью выборки, затем проход по выборке с целью выполнения действия.
Там один проход.
ВВ>Что кстати в твоем примере и видно:
ВВ>[b]AVK>Action 2
Можно логику пояснить, что ты там увидел?
ВВ>А вот в случае с методом ForEach<T>(this IEnumerable<T> source, Action<T> action, Func<bool> condition) проход по коллекции будет вообще один.
Правда? Модифицируем пример:
using System;
using System.Collections.Generic;
namespace WhereForeach
{
static class Program
{
static IEnumerable<int> TestEnum()
{
yield return 1;
Console.WriteLine(1);
yield return 2;
Console.WriteLine(2);
yield return 3;
Console.WriteLine(3);
}
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action, Func<T, bool> filter)
{
foreach (var item in source)
if (filter(item))
action(item);
}
static void Main()
{
TestEnum().ForEach(i => Console.WriteLine("Action " + i), i => i == 2);
}
}
}
Вывод на консоль тот же. Удивительно, правда?
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Вывод на консоль тот же. Удивительно, правда?
Да, интересно, Where не выполняет IEnumerable, а создает обвертку над ним обвертку и выполняет, используя переданное условие. С другой стороны, вполне логичное поведение, странно, что я ожидал что-то другое. Что ж, будем знать
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Да, интересно, Where не выполняет IEnumerable, а создает обвертку над ним обвертку и выполняет, используя переданное условие.
Не не не. Ты мне объясни, каким образом получаются два прохода по итератору, если итератор вызывается ровно один раз? Единственный способ — переписать итератор в массив. Ты уверен в том, что Enumerable.Where это делает?
ВВ> С другой стороны, вполне логичное поведение, странно, что я ожидал что-то другое.
Ну, ты много очень странных мыслей сегодня высказал
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Не не не. Ты мне объясни, каким образом получаются два прохода по итератору, если итератор вызывается ровно один раз? Единственный способ — переписать итератор в массив. Ты уверен в том, что Enumerable.Where это делает?
Да посмотрел я уже Мне казалось, что он и правда куда-то переписывает. Что странно, так как, насколько я вспомнил, я и раньше это смотрел тоже. Видимо, меня зазомбировали.
ВВ>> С другой стороны, вполне логичное поведение, странно, что я ожидал что-то другое. AVK>Ну, ты много очень странных мыслей сегодня высказал
Сегодня странных мыслей вроде бы больше не было... Может, ты про вчерашнее?
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Да посмотрел я уже Мне казалось, что он и правда куда-то переписывает. Что странно, так как, насколько я вспомнил, я и раньше это смотрел тоже.
Ну точно, Михайлик №2
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
Здравствуйте, IB, Вы писали: _FR>>2. Это вопрос самый спорный. IB>Наоборот, самый бесспорный =) plain foreach — чище, очевиднее и понятнее любого метода с Action<T> в качестве аргумента, я не понимаю, какие тут вообще могут быть сомнения..
Единственное место, где екстеншн-метод с Action<T> смотрится более прикольно — это когда вместо замыкания туда передаётся готовый делегат.
Зацени:
public static void Main(string args[])
{
args.ForEach(Console.WriteLine);
}
Это по сравнению с
public static void Main(string args[])
{
foreach(var a in args)
Console.WriteLine(a);
}
Такой способ применения позволяет обойтись без введения временной переменной, весь смысл которой — дотащить текущий элемент до вызова.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>*Вся* работа с последовательностями ли, с базой данных и пр. уж никак не может вестись в одном стиле, о чем уже так долго говорят большевики и с чем, видимо, придется смириться.
Странно. Это какие большевики? Наши большевики как раз говорят о том, что вся встроенная во фреймворк работа с последовательностями ведется в одном стиле.
ВВ>А в данном случае непонятно — откуда возникает требование этого функционального стиля? Если передо мной стоят задачи модификации или, не дай бог, появляются методы имеющие сохраняемое состояние — то причем здесь вообще функциональный стиль? И почему это должно быть функционально, если в действительности это не функционально ни на йоту? ВВ>Это мы только ForEach<> касаемся, а можно еще и рассмотреть всякие Aggregate<> — там ведь вообще ужас с этой точки зрения.
Правда что ли? У Aggrgate<> нет никакого изменяемого состояния.
ВВ>String.Replace — очень схожая задача с обсуждаемой здесь. И совершенно нефункционально. И при этом самая что ни на есть последовательность. В каком стиле предлагаете проводить замену?
Судя по этому примеру, ты не вполне понимаешь, что такое ФП. string.Replace — 100% функциональна. У неё нет побочных эффектов!
ВВ>Функциональному дизайну Линка, который здесь вообще не причем, противоречит императивный стиль?
Функциональному дизайну Linq2Objects, реализованному в хелперах для IEnumerable<T>, противоречит императивный стиль.
ВВ>Вам дали библиотеку со "спецэффектами" и теперь уже стиль у языка другой?
Нам дали библиотеку без спецэффектов.
ВВ>То же самое можно сказать и про Where по сравнению с foreach.
Увы, нельзя. Семантика where не сводится к foreach(var item in source ) if condition(item) action(item).
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
ВВ>>*Вся* работа с последовательностями ли, с базой данных и пр. уж никак не может вестись в одном стиле, о чем уже так долго говорят большевики и с чем, видимо, придется смириться. S>Странно. Это какие большевики? Наши большевики как раз говорят о том, что вся встроенная во фреймворк работа с последовательностями ведется в одном стиле.
Те, которые хотят при работе с linq2sql изменения данных также делать средствами linq. Имена, явки давать?
ВВ>>А в данном случае непонятно — откуда возникает требование этого функционального стиля? Если передо мной стоят задачи модификации или, не дай бог, появляются методы имеющие сохраняемое состояние — то причем здесь вообще функциональный стиль? И почему это должно быть функционально, если в действительности это не функционально ни на йоту? ВВ>>Это мы только ForEach<> касаемся, а можно еще и рассмотреть всякие Aggregate<> — там ведь вообще ужас с этой точки зрения. S>Правда что ли? У Aggrgate<> нет никакого изменяемого состояния.
Хочешь я напишу реализацию, у которой будет? У ForEach<> точно так же нет состояния by design, точно так же можно написать кучу прекрасного кода, в котором никакого состояния и не будет. А можно написать кучу кода с Aggregate<>, у которого будет состояние.
А все потому что, как тут говорят некоторые товарищи, Aggregate<> "вносит тонкую семантику замыкания". Я вот не вижу здесь принципиальной разницы между Aggregate<> и ForEach<>.
ВВ>>String.Replace — очень схожая задача с обсуждаемой здесь. И совершенно нефункционально. И при этом самая что ни на есть последовательность. В каком стиле предлагаете проводить замену? S>Судя по этому примеру, ты не вполне понимаешь, что такое ФП. string.Replace — 100% функциональна. У неё нет побочных эффектов!
Ты судя по всему не вполне прочитал ветку. У меня у ForEach<> тоже побочных эффектов нет. Это Фред вот заговорил о том, что ф-ция ForEach<> в предлагаемом варианте плоха, т.к. она совмещает два действия — применить некое действие к элементам массива, выполнить условие — и советовал использовать "функциональную декомпозицию". Я ему посоветовал использовать функциональную декомпозицию для String.Replace.
ВВ>>Функциональному дизайну Линка, который здесь вообще не причем, противоречит императивный стиль? S>Функциональному дизайну Linq2Objects, реализованному в хелперах для IEnumerable<T>, противоречит императивный стиль.
А причем здесь эти хелперы? Речь не о том, стоило ли включать ForEach<> в пространство имен Линк. Я этого вообще никогда не предлагал. Речь о том, является ли ф-ция ForEach<> абсолютным и беспрекословным злом.
И как я уже говорил "угроза подобных эффектов" там не выше чем у того же Aggregate<>.
ВВ>>То же самое можно сказать и про Where по сравнению с foreach. S>Увы, нельзя. Семантика where не сводится к foreach(var item in source ) if condition(item) action(item).
Разве Where не "добавляет семантику замыкания, потенциально внося тонкие изменения в жизненные циклы объектов"? Тебе привести пример Where с подобными эффектами?
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Те, которые хотят при работе с linq2sql изменения данных также делать средствами linq. Имена, явки давать?
Всё наоборот — дедушка хотел, чтобы не было бедных.
То есть как раз хочется провести чёткую границу между "ФП без побочных эффектов" и "описанием побочных эффектов".
ВВ>Хочешь я напишу реализацию, у которой будет?
Нет, не хочу. ВВ>У ForEach<> точно так же нет состояния by design, точно так же можно написать кучу прекрасного кода, в котором никакого состояния и не будет. Единственный смысл ForEach — получение побочных эффектов. Это понятно?
ВВ>А все потому что, как тут говорят некоторые товарищи, Aggregate<> "вносит тонкую семантику замыкания". Я вот не вижу здесь принципиальной разницы между Aggregate<> и ForEach<>.
Принципиальная разница — в том, что Aggregate остаётся ленивым. Семантика замыкания в его случае полностью оправдана — мы всё еще описываем способ получения одних данных из других. В случае ForEach мы имеем энергичную семантику "немедленно примени мне здесь побочные эффекты, которые я описал в Action<T>".
ВВ>Ты судя по всему не вполне прочитал ветку. У меня у ForEach<> тоже побочных эффектов нет.
Да ладно!
Если у него нет побочных эффектов, то его можно просто не вызывать.
ВВ>А причем здесь эти хелперы? Речь не о том, стоило ли включать ForEach<> в пространство имен Линк. Я этого вообще никогда не предлагал. Речь о том, является ли ф-ция ForEach<> абсолютным и беспрекословным злом.
Конечно же нет. Например, функция List<T>.ForEach беспрекословным злом не является. А вот хелпер для IEnumerable — является, о чём недвусмысленно написал Эрик.
ВВ>Разве Where не "добавляет семантику замыкания, потенциально внося тонкие изменения в жизненные циклы объектов"?
Нет, не добавляет. Жизненные циклы объектов, обрабатываемых в Where, изначально продлены — из-за его ленивости. Поэтому замыкание не шибко влияет на результат. ВВ>Тебе привести пример Where с подобными эффектами?
Круче, чем у Барта, у тебя вряд ли получится
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Единственный смысл ForEach — получение побочных эффектов. Это понятно?
Это ты сам сейчас придумал. А для меня ForEach отличается от Aggregate только отсутствием аккумулятора и возвращаемого значения, что для настоящих джедаев не помеха при написании пьюре функции.
ВВ>>А все потому что, как тут говорят некоторые товарищи, Aggregate<> "вносит тонкую семантику замыкания". Я вот не вижу здесь принципиальной разницы между Aggregate<> и ForEach<>. S>Принципиальная разница — в том, что Aggregate остаётся ленивым. Семантика замыкания в его случае полностью оправдана — мы всё еще описываем способ получения одних данных из других. В случае ForEach мы имеем энергичную семантику "немедленно примени мне здесь побочные эффекты, которые я описал в Action<T>".
Так сделаем ForEach ленивым
ВВ>>Ты судя по всему не вполне прочитал ветку. У меня у ForEach<> тоже побочных эффектов нет. S>Да ладно! S>Если у него нет побочных эффектов, то его можно просто не вызывать.
Да ладно. У тебя просто фантазия неразвита
Даю хинт — никто не запрещает в чистых функциях генерировать исключения.
ВВ>>А причем здесь эти хелперы? Речь не о том, стоило ли включать ForEach<> в пространство имен Линк. Я этого вообще никогда не предлагал. Речь о том, является ли ф-ция ForEach<> абсолютным и беспрекословным злом. S>Конечно же нет. Например, функция List<T>.ForEach беспрекословным злом не является. А вот хелпер для IEnumerable — является, о чём недвусмысленно написал Эрик.
Эрик писал что:
— бла-бла-бла, поэтому этого нет в пространстве имен Лин
— бла-бла-бла, я считаю, что эта функция с философской точки зрения полный отстой, но если вам так хочется, реализуйте ее сами.
Как-то мне сложно из этого сделать вывод, что List<T>.ForEach это нормально, а IEnumerable.ForEach — зло.
А вообще причем тут побочные эффекты и проч.? Не нравится использовать замыкания для побочных эффектов? А каллбеки вообще можно использовать? К чему суть спора сводится-то?
Здравствуйте, Sinclair, Вы писали:
S>Например, функция List<T>.ForEach беспрекословным злом не является. А вот хелпер для IEnumerable — является, о чём недвусмысленно написал Эрик.
Вот ещё один толкователь Мужики, вы понятным языком можете рассказать, что и где вы там видите или сами понимаете?
Ключевой смысл, я полагаю, имеет предложение
Мне как-то не нравится идея сделать единственный оператор для последовательностей, который полезен только для спецэффектов.
Но что в этом плохого? Ведь есть же какие-то причины? Или это всё на уровне подсознания?
Почему-то из критиков тут никто ещё не продвинулся дальше этого "не нравится"
Методов, имеющих своей целью создание побочных эффектов множество. Они все не правы? Или именно ForEach на их фоне чем-то выделяется? Ну хоть забань меня модератор, не вижу чем же именно
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Sinclair, Вы писали:
S>Например, функция List<T>.ForEach беспрекословным злом не является. А вот хелпер для IEnumerable — является, о чём недвусмысленно написал Эрик.
Отличный пример! Разве целью приведённого решения не является создание побочных эффектов? А насколько такое решение "функционально"?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Это ты сам сейчас придумал.
Нет. Читать здесь.
Покажи мне применение ForEach, в котором нет побочных эффектов. ВВ>А для меня ForEach отличается от Aggregate только отсутствием аккумулятора и возвращаемого значения, что для настоящих джедаев не помеха при написании пьюре функции.
pure function без возвращаемого значения эквивалентна {}. Это знают даже падаваны, а уж настоящим джедаям это положено знать — иначе лайтсабер никто не даст.
ВВ>Так сделаем ForEach ленивым
Можно в студию пример ленивого форича?
ВВ>Даю хинт — никто не запрещает в чистых функциях генерировать исключения.
Это и будет побочным эффектом.
ВВ>А вообще причем тут побочные эффекты и проч.? Не нравится использовать замыкания для побочных эффектов? А каллбеки вообще можно использовать? К чему суть спора сводится-то?
К тому, что некоторые люди не могут понять простую и короткую статью даже после многократного прочтения. Больше никакой сути в споре нету.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, _FRED_, Вы писали:
_FR>Вот ещё один толкователь Мужики, вы понятным языком можете рассказать, что и где вы там видите или сами понимаете?
_FR>Ключевой смысл, я полагаю, имеет предложение _FR>
Мне как-то не нравится идея сделать единственный оператор для последовательностей, который полезен только для спецэффектов.
_FR>Но что в этом плохого?
В том, что он будет единственным. Это нарушает вселенскую симметрию linq2objects.
В классе List<T> дохрена методов, рассчитанных на побочные эффекты, поэтому там (как и в Array) ForEach уместен. Для IEnumerable он будет слишком неожиданным.
_FR>Методов, имеющих своей целью создание побочных эффектов множество.
В Linq2Objects таких методов нет.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, _FRED_, Вы писали: _FR>Отличный пример! Разве целью приведённого решения не является создание побочных эффектов? А насколько такое решение "функционально"?
Абсолютно нефункционально. Это специальная штука, которая придаёт побочные эффекты тому, у чего их не было — для того, чтобы ты мог визуально наблюдать "путь исполнения" декларативного запроса.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
_FR>>Вот ещё один толкователь Мужики, вы понятным языком можете рассказать, что и где вы там видите или сами понимаете?
_FR>>Ключевой смысл, я полагаю, имеет предложение _FR>>
Мне как-то не нравится идея сделать единственный оператор для последовательностей, который полезен только для спецэффектов.
_FR>>Но что в этом плохого? S>В том, что он будет единственным. Это нарушает вселенскую симметрию linq2objects. S>В классе List<T> дохрена методов, рассчитанных на побочные эффекты, поэтому там (как и в Array) ForEach уместен. Для IEnumerable он будет слишком неожиданным.
_FR>>Методов, имеющих своей целью создание побочных эффектов множество. S>В Linq2Objects таких методов нет.
Спасибо, то что надо.
Какое отношение этот вот метод
static class Sequence
{
public static void ForEach<TSource>(this IEnumerable<TSource> source, Action<TSource> action) {
foreach(var item in source) {
action(item);
}//for
}
}
имеет к a) Linq2Objects б) IEnumerable ц) дизайну языка C#
Help will always be given at Hogwarts to those who ask for it.