Re[5]: LINQ & Except
От: Воронков Василий Россия  
Дата: 11.06.09 08:12
Оценка:
Здравствуйте, Ziggi111, Вы писали:

Z>ИМХО

Z>
Z>list.ForEach(x => DoSmth(x), x => Condition(x));
Z>

Z>читается не лучше, но, как и сказано в указанном блоге, недебагебелбно

Это в блоге "недебагебелбно" У меня-то все дебагебельно — код в соседней сборке лежит
Re[8]: LINQ & Except
От: Ziaw Россия  
Дата: 11.06.09 08:17
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>На мой взгляд преимущество тут точно такое же как и у простого Where(x => Condition(x)) перед if (Condition(x)) {} — когда "букаф" даже больше получается.


В отличии от ForEach/foreach они не эквивалентны. Для функцифонального стиля уже есть аналог foreach, это Select(). Все что выходит за рамки селекта почти наверняка будет нести побочные эффекты и придавать этому вид функции означает запутать читателя.

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


В каком месте?
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[4]: LINQ & Except
От: _FRED_ Черногория
Дата: 11.06.09 08:23
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

IB>>http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx


ВВ>Ну и что? Там высказано частное мнение, что ForEach в таком виде это вообще плохо. Основная причина, что противоречит принципам функционального программирования. Я как-то не припомню, чтобы C# стал pure functional language. Лично мне запись вида:


ВВ>list.ForEach(x => DoSmth(x), x => Condition(x));


В таком виде эта запись действительно не нужна — слишком много на себя берёт.
list.Where(x => Condition(x)).ForEach(x => DoSmth(x));

или вообще так:
list.Where(Condition).ForEach(DoSmth);
Help will always be given at Hogwarts to those who ask for it.
Re[9]: LINQ & Except
От: Воронков Василий Россия  
Дата: 11.06.09 08:25
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>В отличии от ForEach/foreach они не эквивалентны. Для функцифонального стиля уже есть аналог foreach, это Select().


Селект — это не аналог foreach.

Z>Все что выходит за рамки селекта почти наверняка будет нести побочные эффекты и придавать этому вид функции означает запутать читателя.


А причем тут функциональный стиль?

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

Z>В каком месте?

В одном у меня есть кондишин, в другом — нет.

Вообще я не понимаю, т.е. все отписавшиеся считают, что то, что в этом блоге написано — святая истина и вопрос полностью закрыт? Тут домен блога оказывает какое-то особое воздействие или же просто сам факт, что это блог? Если я заведу блог и напишу, что нельзя использовать Where, потому что:

1. В общем случае код не становится короче (а иногда — даже длиннее)
2. Дебажить неудобно (а как вы будете дебажить Where(x => x == y)?)
и прочее в том же духе.

То вы не будете Where использовать?

Единственный аргумент там — то, что ForEach — это не функционально. Аргумент весьма своеобразный на мой взгляд. Я вот никогда не видел приложение на шарпе написанное целиком функционально. Да и в Линк при желании можно запихать побочных эффектов по самое не могу — и все будет прекрасно работать.

Может, в таком случае выбор языке не совсем правильный?
Re[3]: LINQ & Except
От: _FRED_ Черногория
Дата: 11.06.09 08:27
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Воронков Василий, Вы писали:


ВВ>>Вообще касательно ForEach я потихоньку пришел к выводу, что не грех самом деле свой ForEach написать. С т.з. лаконичности кода это окупиться сто раз, к тому же часто приходится работать и с коллекциями, которые восходят к не-генерик интерфейсам — и можно сделать универсальную реализацию, которая позволит избежать лишних преобразований.


IB>http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx


Мне показалось, что статья объясняет то, "почему Microsoft не предоставила для последовательностей метод расширения ForEach". Среди методов System.Linq.Enumerable.* ForEach действительно смотрелся бы странно.
Help will always be given at Hogwarts to those who ask for it.
Re[2]: LINQ & Except
От: IB Австрия http://rsdn.ru
Дата: 11.06.09 08:34
Оценка: 6 (1)
Здравствуйте, Sinix, Вы писали:

S>А то тут уже linq к парсингу строк прикрутить пытались.

Не знаю насчет строк, а вот впринципе парсер, довольно прикольный получился.. Но это, конечно, разминка для ума, а не продакшн код. (http://blogs.gotdotnet.ru/personal/bezzus/CommentView.aspx?guid=01b332c8-641e-4888-97ae-2de6d74aa511)
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[6]: LINQ & Except
От: IB Австрия http://rsdn.ru
Дата: 11.06.09 08:34
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Ну если оперировать теми же аргументами, что и в приведенном здесь блоге, то этот вариант практически идентичен вышеприведенному — ведь кол-во символов практически то же:

Ну, ты бы хоть по русски прочитал, если в оригинале не очень понятно, тем более, что ссылку уже дали.
Действительно, зря что ли Синклер старался? http://blogs.msdn.com/ruericlippert/archive/2009/05/18/foreach-foreach.aspx

ВВ>Вывод, мне кажется, каждый делает сам..

Угу.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[5]: LINQ & Except
От: Воронков Василий Россия  
Дата: 11.06.09 08:35
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>В таком виде эта запись действительно не нужна — слишком много на себя берёт.

_FR>
_FR>list.Where(Condition).ForEach(DoSmth);
_FR>


А можно обосновать этот критерий — "слишком много"?
Применить действие Х по условию Y — вполне нормальная операция на мой взгляд.
Ты меняешь это на две операции:
Выбрать по условию Y
Применить действие Х для выбранного
Два раза бежим по списку — ну да бог с ним. Главное, какое проблема решена в результате? Ни одна из описываемых здесь "проблем" — не решается. И главное —

foreach (var x in list) if (Condition(x)) DoSmth(x);


по-прежнему самая короткая запись
Re[7]: LINQ & Except
От: Воронков Василий Россия  
Дата: 11.06.09 08:37
Оценка: :)
Здравствуйте, IB, Вы писали:

ВВ>>Ну если оперировать теми же аргументами, что и в приведенном здесь блоге, то этот вариант практически идентичен вышеприведенному — ведь кол-во символов практически то же:

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

Спасибо, я читаю по-английски. И никакого "послания" кроме как это "нефукционально" я там не вижу. Все остальные "недостатки" точно также применимы и для Линк.

ВВ>>Вывод, мне кажется, каждый делает сам..

IB>Угу.
Re[4]: LINQ & Except
От: IB Австрия http://rsdn.ru
Дата: 11.06.09 08:40
Оценка: +1
Здравствуйте, _FRED_, Вы писали:

_FR>Мне показалось, что статья объясняет то, "почему Microsoft не предоставила для последовательностей метод расширения ForEach". Среди методов System.Linq.Enumerable.* ForEach действительно смотрелся бы странно.

Эти же аргументы подходят и для того, чтобы не делать свой extension ForEach.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[5]: LINQ & Except
От: _FRED_ Черногория
Дата: 11.06.09 08:41
Оценка:
Здравствуйте, Ziaw, Вы писали:

ВВ>>foreach (var x in list)
ВВ>>  if (Condition(x))
ВВ>>    DoSmth(x);


Z>Если же в ForEach оставить только экшен — у него не останется преимуществ перед foreach.


Как так "не останется"? Например по guidelines принятым у нас в конторе guidelines вышеприведённый код расползается — угадай, на сколько строк?
1: foreach (var x in list)
2: {
3:   if (Condition(x))
4:   {
5:     DoSmth(x);
6:   }
7: }

и это предлагается вместо
list.Where(Condition).ForEach(DoSmth);

Help will always be given at Hogwarts to those who ask for it.
Re[10]: LINQ & Except
От: Ziaw Россия  
Дата: 11.06.09 08:46
Оценка: -1
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Селект — это не аналог foreach.


if -> Where()
точно также как и
foreach -> Select()

ВВ>А причем тут функциональный стиль?


при топике

ВВ>Вообще я не понимаю, т.е. все отписавшиеся считают, что то, что в этом блоге написано — святая истина и вопрос полностью закрыт? Тут домен блога оказывает какое-то особое воздействие или же просто сам факт, что это блог?


То, что это блог Эрика Липперта. Впрочем я не беру на веру все блоги, к данному выводу я пришел сам до чтения.

ВВ>Если я заведу блог и напишу, что нельзя использовать Where, потому что:


ВВ>1. В общем случае код не становится короче (а иногда — даже длиннее)

ВВ>2. Дебажить неудобно (а как вы будете дебажить Where(x => x == y)?)
ВВ>и прочее в том же духе.

ВВ>То вы не будете Where использовать?


Если предложите аналог заменяющий Where во всех сценариях использования можно будет обсуждать.

ВВ>Единственный аргумент там — то, что ForEach — это не функционально. Аргумент весьма своеобразный на мой взгляд. Я вот никогда не видел приложение на шарпе написанное целиком функционально. Да и в Линк при желании можно запихать побочных эффектов по самое не могу — и все будет прекрасно работать.


А я и не предлагаю писать все предложение функционально, я предлагаю не писать в функциональном стиле императивный код.
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[6]: LINQ & Except
От: _FRED_ Черногория
Дата: 11.06.09 08:47
Оценка: +1
Здравствуйте, Воронков Василий, Вы писали:

_FR>>В таком виде эта запись действительно не нужна — слишком много на себя берёт.

_FR>>list.Where(Condition).ForEach(DoSmth);

ВВ>А можно обосновать этот критерий — "слишком много"?

Конечно: SRP, "Разделяй и влавствуй" и прочее и прочее — две функции, каждая из которых решает какую-то одну маленькую задачу лучше чем одна, решающая две две, что первые можно комбинировать. Вот пример — сколько у тебя сейчас перегрузок ForEach? Допустим, две:
void ForEach<T>(this IEnumerable<T>, Action<T>);
void ForEach<T>(this IEnumerable<T>, Predicate<T>, Action<T>);

Но вот у меня есть ещё варианты ForEach, передающие в Action два параметра — элемент и его индекс. Тебе, что бы этого добиться и поддржать согласованость API придётся добавить две перегрузки:
void ForEach<T>(this IEnumerable<T>, Action<T, int>);
void ForEach<T>(this IEnumerable<T>, Predicate<T>, Action<T, int>);
Help will always be given at Hogwarts to those who ask for it.
Re[6]: LINQ & Except
От: Ziaw Россия  
Дата: 11.06.09 08:48
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Как так "не останется"? Например по guidelines принятым у нас в конторе guidelines вышеприведённый код расползается — угадай, на сколько строк?


foreach (var x in list.Where(Condition))
{
  DoSmth(x);
}


Не очень убеждает.
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[6]: LINQ & Except
От: Ziaw Россия  
Дата: 11.06.09 08:48
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Два раза бежим по списку — ну да бог с ним.


Бежим один раз.
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[5]: LINQ & Except
От: _FRED_ Черногория
Дата: 11.06.09 08:56
Оценка:
Здравствуйте, IB, Вы писали:

_FR>>Мне показалось, что статья объясняет то, "почему Microsoft не предоставила для последовательностей метод расширения ForEach". Среди методов System.Linq.Enumerable.* ForEach действительно смотрелся бы странно.

IB>Эти же аргументы подходят и для того, чтобы не делать свой extension ForEach.

Вот первый:

Во-первых, это нарушило бы принципы функционального программирования, на которых основаны все остальные операторы на последовательностях.


foreach как-то вообще не очень совместим с "принципами функционального программирования", так что этот пункт обсуждать неинтересно. Или я не прав?

Во-вторых, такая возможность ничего не добавляет к выразительности языка. Она всего лишь позволяет вам переписать вот этот идеально понятный код… (в другом виде [прим. _FRED_])


Да, позволяет переписать "в другом". А что тут некошерного?

И вторую версию даже труднее понять и отладить, …


В том виде как это показывает Эрик:

foos.ForEach((Foo foo)=>{ какой-то оператор с foo; });

да, но есть же и более простые случаи:
foos.ForEach(DoSmth);


а еще она добавляет семантику замыкания, потенциально внося тонкие изменения в жизненные циклы объектов.


Это так же относится к злоупотреблению. Но со "злоупотреблением" нужно бороться другими методами, такими как рефакторинг, например.
Help will always be given at Hogwarts to those who ask for it.
Re[7]: LINQ & Except
От: _FRED_ Черногория
Дата: 11.06.09 09:02
Оценка:
Здравствуйте, Ziaw, Вы писали:

_FR>>Как так "не останется"? Например по guidelines принятым у нас в конторе guidelines вышеприведённый код расползается — угадай, на сколько строк?

Z>foreach (var x in list.Where(Condition))
Z>{
Z>  DoSmth(x);
Z>}

Z>Не очень убеждает.

Расскажи пожалуйста о преимуществах Where в данном конкретном примере над if.
Help will always be given at Hogwarts to those who ask for it.
Re[6]: LINQ & Except
От: _FRED_ Черногория
Дата: 11.06.09 09:06
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Это так же относится к злоупотреблению. Но со "злоупотреблением" нужно бороться другими методами, такими как рефакторинг, например.


Здесь я имел в виду то, что когда метод в ForEach становится сложным, и читать и отлаживать действительно непросто. Но сложно [плохо] написанный код тяжело поддаётся отладке во многих случаях и не потому что не надо "вредных" методов добавлять, а потому что не нужно сложно писать. А если писать "не сложно", то проблем с отладкой и читабельностью не будет.
Help will always be given at Hogwarts to those who ask for it.
Re[11]: LINQ & Except
От: Воронков Василий Россия  
Дата: 11.06.09 09:09
Оценка:
Здравствуйте, Ziaw, Вы писали:

ВВ>>Селект — это не аналог foreach.

Z>if -> Where()
Z>точно также как и
Z>foreach -> Select()

Правда что ли? Как же вы это сравниваете императивные конструкции и функциональными?

ВВ>>А причем тут функциональный стиль?

Z>при топике

Ну так перечитайте первое сообщение.

Z>Если предложите аналог заменяющий Where во всех сценариях использования можно будет обсуждать.


foreach

ВВ>>Единственный аргумент там — то, что ForEach — это не функционально. Аргумент весьма своеобразный на мой взгляд. Я вот никогда не видел приложение на шарпе написанное целиком функционально. Да и в Линк при желании можно запихать побочных эффектов по самое не могу — и все будет прекрасно работать.

Z>А я и не предлагаю писать все предложение функционально, я предлагаю не писать в функциональном стиле императивный код.

Таким образом мысль блога сводится к тому, что single statement lambda нельзя использовать в тех случаях, когда у нас есть побочные эффекты. Что предлагается взамен? Использовать простые делегаты, анонимные делегаты, заставлять себя вставлять фигурные скобки даже если лямбда состоит из одного выражения? Вывод какой? Или это так — просто потрепаться? Если я напишу:

list.ForEach(x => { DoSmth(x); });


То все, проблема снята? Или лучше вообще:

list.ForEach(delegate(Type x) => { DoSmth(x); });


Никакого функционального стиля, ага?
А теперь смотрим на саму функцию:

static void ForEach<T>(this IEnumerable<T> inst, Action<T> act) {...}


Возникает вопрос — а какой именно код написан функционально? Что вы предлагаете не писать в функциональном стиле? Использовать другой синтаксис для передачи колл-беков?

Используйте любой синтаксис, если считаете ввод подобных ограничений разумным. Только вот вопроса с ForEach и foreach это никак не касается.
Re[7]: LINQ & Except
От: Воронков Василий Россия  
Дата: 11.06.09 09:11
Оценка:
Здравствуйте, Ziaw, Вы писали:

ВВ>>Два раза бежим по списку — ну да бог с ним.

Z>Бежим один раз.

К сожалению, Линк не предоставляет нормальных средств для дебага — а так бы увидели, что это не так
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.