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

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


Пример с ForEach не есть на нарушение SRP. Выполнить действие Х по условию У — это одна задача в императивном мире. Попробуй *все* функции на шарпе писать так, как ты предлагаешь, делая действия максимально атомарными, и огребешь кучу проблем — это с императивными-то функциями.

А ты сейчас принципы функционального программирования — атомарные ф-ции и все такое — пытаешься наложить на императивное. ForEach — не функционален. А разговор на самом деле идет о том, какой синтаксис использовать для его вызова

_FR>
_FR>void ForEach<T>(this IEnumerable<T>, Action<T>);
_FR>void ForEach<T>(this IEnumerable<T>, Predicate<T>, Action<T>);
_FR>

_FR>Но вот у меня есть ещё варианты ForEach, передающие в Action два параметра — элемент и его индекс. Тебе, что бы этого добиться и поддржать согласованость API придётся добавить две перегрузки:
_FR>
_FR>void ForEach<T>(this IEnumerable<T>, Action<T, int>);
_FR>void ForEach<T>(this IEnumerable<T>, Predicate<T>, Action<T, int>);
_FR>


А в твоем случае красивее будет?
Re: LINQ & Except
От: _FRED_ Черногория
Дата: 11.06.09 09:17
Оценка: :)
Здравствуйте, Tom, Вы писали:

Tom>Вопрос, можно как то ещё упростить такой вот запрос:

Tom>var servicesInDatabase = new List<string>() {"s1", "s2", "s3", "s10"};
Tom>var servicesLocal = new List<string>() { "s1", "s2", "s4", "s5"};

Tom>servicesInDatabase.Except(servicesLocal).ToList().ForEach(Console.WriteLine /*Actually we'to DELETE services here*/);
Tom>servicesLocal.Except(servicesInDatabase).ToList().ForEach(Console.WriteLine /*Actually we'to CREATE services here*/);


Операции над наборами производятся разные, поэтому "объединять" наборы, ИМХО, не нужно.
".ToList()" только для ".ForEach" ИМХО, перебор — или пользоваться своим "ForEach<T>(IEnumerable<T>…" или foreach — это зависит от того, как ты трактуешь Тору…, нет, Липперта
Help will always be given at Hogwarts to those who ask for it.
Re[8]: LINQ & Except
От: _FRED_ Черногория
Дата: 11.06.09 09:19
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>А в твоем случае красивее будет?


В моём случае я имею только два метода:
void ForEach<T>(this IEnumerable<T>, Action<T>);
void ForEach<T>(this IEnumerable<T>, Action<T, int>);

Так как Where есть стандартный. И когда понадобится добавить что-то ещё в сигнатуру вызова, у меня и добавляется столько методов, сколько изменений требуется, а в твоём случае — приходится умножать на два.
Help will always be given at Hogwarts to those who ask for it.
Re[2]: LINQ & Except
От: Аноним  
Дата: 11.06.09 09:29
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Во-первых используем HashSet.


А зачем? Except внутри и сам использует Set (который hash):
[CompilerGenerated]
private sealed class <ExceptIterator>d__92<TSource> : IEnumerable<TSource>, IEnumerable, IEnumerator<TSource>, IEnumerator, IDisposable
{
    // Fields
    private int <>1__state;
    private TSource <>2__current;
    public IEqualityComparer<TSource> <>3__comparer;
    public IEnumerable<TSource> <>3__first;
    public IEnumerable<TSource> <>3__second;
    public IEnumerator<TSource> <>7__wrap95;
    private int <>l__initialThreadId;
    public TSource <element>5__94;
    public Set<TSource> <set>5__93;
    public IEqualityComparer<TSource> comparer;
...
...
}
Re[9]: LINQ & Except
От: Воронков Василий Россия  
Дата: 11.06.09 09:33
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Так как Where есть стандартный. И когда понадобится добавить что-то ещё в сигнатуру вызова, у меня и добавляется столько методов, сколько изменений требуется, а в твоём случае — приходится умножать на два.


Хорошо, а с чем боремся-то? Сократить кол-во функций любой ценой? Так ты же говорил, что функции должны быть атомарными, что их будет много и так далее.
Потом на самом деле в моем случае придется делать перегрузки одной функции, а в твоем, если уж честно рассматривать разнообразные сценарии, двух. И преимущество опять-таки непонятно.

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

А проблема-то на самом деле уходит корнями в тот факт, что нам предложили красивый и модный синтаксис для выборок, а вот для изменений, которые как бы не менее редкие, не предложили. Что особенно явно и чувствуется на примере какого-нибудь linq2sql. Недаром товарищи вроде ИТ да Влада бьются как бы эти самые лямбды к инсертам да апдейтам прикрутить, используя весьма функциональный синтаксис для весьма, надо сказать, императивных действий. И да, с одной стороны, неправильно это, о чем я сам, кстати, и говорил А с другой стороны — что делать? То, что ты предлагаешь — это тоже не вариант. Это вообще франкейнштейн какой-то.
Re[6]: LINQ & Except
От: Ziggi111 Россия  
Дата: 11.06.09 09:46
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

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


Z>>ИМХО

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

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

ВВ>Это в блоге "недебагебелбно" У меня-то все дебагебельно — код в соседней сборке лежит

ага... и на каждый ForEach туда падает... чудо а не дебаг...
я не против такой реализации, сам так иногда делаю, но в какой-то момент понял, что Липперт прав
Re[8]: LINQ & Except
От: Ziaw Россия  
Дата: 11.06.09 09:47
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR> Расскажи пожалуйста о преимуществах Where в данном конкретном примере над if.


Наглядность, мы сразу видим, что идем по отфильтрованному списку.

В случае с if нам нужно:
1. Увидеть паттерн foreach/if
2. Понять, что условие там зависит только от элемента

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

_FR>>Так как Where есть стандартный. И когда понадобится добавить что-то ещё в сигнатуру вызова, у меня и добавляется столько методов, сколько изменений требуется, а в твоём случае — приходится умножать на два.


ВВ>Хорошо, а с чем боремся-то? Сократить кол-во функций любой ценой?


Не "любой", а просто "Сократить кол-во функций".

ВВ>Так ты же говорил, что функции должны быть атомарными, что их будет много и так далее.


Что их _может быть_ много. Когда каждая выполняет строго одну задачу, мы можем справляться с необходимостью расширения функционала с посредством комбинирования. В твоём же случае и _лишним_ параметром-предикатом это приводит к дублированию.

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


Как так? Давай говорить не-абстрактно: покажи сигнатуры всех твохи перегрузок ForEach? У меня их всего две (здесь
Автор: _FRED_
Дата: 11.06.09
).

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


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

_FR>> Расскажи пожалуйста о преимуществах Where в данном конкретном примере над if.

Z>Наглядность, мы сразу видим, что идем по отфильтрованному списку.

Здесь кто-то не видит, что мы "идем по отфильтрованному списку"?
list.Where(Condition).ForEach(DoSmth);


Z>В случае с if нам нужно:

Z>1. Увидеть паттерн foreach/if
Z>2. Понять, что условие там зависит только от элемента
Z>Два действия вместо одного.

Как контр-аргумент могу привести непригодность к рефакторингу варианта c Where — если понадобится как-то особым образом обработать элементы, не удовлетворяющие условию, придётся писать больше кода, нежели в случае, если бы if стоял бы внутри for.

С другой стороны, все эти "Наглядность, Увидеть, Понять" как раз попадают под слова

…такая возможность ничего не добавляет к выразительности языка…

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

…Когда мы предоставляем два почти одинаковых способа сделать в точности одну вещь, мы вносим сумятицу в индустрию, мы затрудняем людям чтение кода друг друга, и так далее

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

_FR>Здесь кто-то не видит, что мы "идем по отфильтрованному списку"?

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


Здесь вообще нет уверенности что мы идем по нему. =) linq ленив.

_FR>Как контр-аргумент могу привести непригодность к рефакторингу варианта c Where — если понадобится как-то особым образом обработать элементы, не удовлетворяющие условию, придётся писать больше кода, нежели в случае, если бы if стоял бы внутри for.


Да нет никакой обработки во Where(), есть только выборка. Если нам нужно обработать все — нам не нужно Where вообще. Два разных подхода — выбрать то что нужно (функция, результат на ладони, можно вызвать сколько угодно раз, может быть ленива) и обработать (действие, должно быть выполнено один и только один раз, результат за кадром).

Функциональный стиль отлично работает и естественно смотрится в выборке и плохо в обработке.
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[11]: LINQ & Except
От: _FRED_ Черногория
Дата: 11.06.09 10:22
Оценка:
Здравствуйте, Ziaw, Вы писали:

_FR>>Здесь кто-то не видит, что мы "идем по отфильтрованному списку"?

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


Z>Здесь вообще нет уверенности что мы идем по нему. =) linq ленив.


При чём здесь linq? метод Where осуществляет выборку, ForEach — действие.

_FR>>Как контр-аргумент могу привести непригодность к рефакторингу варианта c Where — если понадобится как-то особым образом обработать элементы, не удовлетворяющие условию, придётся писать больше кода, нежели в случае, если бы if стоял бы внутри for.


Z>Да нет никакой обработки во Where(), есть только выборка.


Я нигде и не говорил, про обработку "во Where()". Прочитай пожалуйста внимательнее.

Z>Если нам нужно обработать все — нам не нужно Where вообще.


Я говорил о том, что если нам понадобится как-то обработать то, что не прошло через Where() то переписывать придётся больше, чем в случае с if.

Z>Два разных подхода — выбрать то что нужно (функция, результат на ладони, можно вызвать сколько угодно раз, может быть ленива) и обработать (действие, должно быть выполнено один и только один раз, результат за кадром).

Z>Функциональный стиль отлично работает и естественно смотрится в выборке и плохо в обработке.

Какое это имеет отношение к тому, что я написал?
Help will always be given at Hogwarts to those who ask for it.
Re[11]: LINQ & Except
От: Lloyd Россия  
Дата: 11.06.09 10:22
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>if -> Where()

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


foreach — это while, while — это if + goto => Select == Where + goto
Re[11]: LINQ & Except
От: Аноним  
Дата: 11.06.09 10:23
Оценка: 14 (1)
Здравствуйте, Ziaw, Вы писали:

Z>Здесь вообще нет уверенности что мы идем по нему. =) linq ленив.


зачем же все утрировать, берем исходный вариант конструкции
        public static void ForEach(this IEnumerable collection, Action<object> func)
        {
            foreach (object value in collection)
                func(value);
        }


где производится операция над последовательностью, что естественно (!) и к Linq не имеет отношения.

з.ы. тогда уж обвиняйте расширяющие методы, ну никак не данный ForEach
Re[11]: LINQ & Except
От: Воронков Василий Россия  
Дата: 11.06.09 10:48
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>То, что я предлагаю называется функциональной декомпозицией и к "функциональному стилю" отношения не имеет никакого, поскольку применима в любом стиле программирования (при наличии подпрограмм).


Да ты что? Давай тогда быть последовательными, товарищ. Как ты производишь замену внутри строки, чтобы была "функциональная декомпозиция" и не было "нарушения SRP"?

Я делаю String.Replace.
Re[7]: LINQ & Except
От: Воронков Василий Россия  
Дата: 11.06.09 10:51
Оценка:
Здравствуйте, Ziggi111, Вы писали:

ВВ>>Это в блоге "недебагебелбно" У меня-то все дебагебельно — код в соседней сборке лежит

Z>ага... и на каждый ForEach туда падает...

Куда падает? Я дебажить буду саму реализацию ф-ции ForEach.

Z>чудо а не дебаг...


А Линк вы как дебажите? Ровно та же проблема.

Z>я не против такой реализации, сам так иногда делаю, но в какой-то момент понял, что Липперт прав


Ну правильно, они прикрутили к бабе яйца, а теперь же надо какие-то рекомендации для народа придумывать. Типа в этой позе можно, а в этой уже... эээ... "неженственно". А что они раньше-то думали?
Re[12]: LINQ & Except
От: _FRED_ Черногория
Дата: 11.06.09 10:51
Оценка: -1
Здравствуйте, Воронков Василий, Вы писали:

_FR>>То, что я предлагаю называется функциональной декомпозицией и к "функциональному стилю" отношения не имеет никакого, поскольку применима в любом стиле программирования (при наличии подпрограмм).


ВВ>Да ты что? Давай тогда быть последовательными, товарищ.


Давайте не будем уходить в сторону абсурда, Уважаемый. Я лишь сказал Вам, что неплохо бы выкинуть нафик один из параметров Вашего метода ибо он не нужен. Учить Вас писать код и производить с Вами замены в строчках мне ни сколечки не улыбается, с SRP или без оного.
Help will always be given at Hogwarts to those who ask for it.
Re[13]: LINQ & Except
От: Воронков Василий Россия  
Дата: 11.06.09 11:00
Оценка: -2
Здравствуйте, _FRED_, Вы писали:

_FR>Давайте не будем уходить в сторону абсурда, Уважаемый. Я лишь сказал Вам, что неплохо бы выкинуть нафик один из параметров Вашего метода ибо он не нужен. Учить Вас писать код и производить с Вами замены в строчках мне ни сколечки не улыбается, с SRP или без оного.


Лучше ты сам научись, как писать код, а не рассуждать о высоких материях. Посмотрел бы я на код реальных проектов, написанный с подобных позиций и на то, как хорошо он работает.
String.Replace ему не нравится видите ли, так нарушение же single responsibility — и ищем, и заменяем.
Re[8]: LINQ & Except
От: IB Австрия http://rsdn.ru
Дата: 11.06.09 13:02
Оценка: +3
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Спасибо, я читаю по-английски.

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

1. Речь не о том, что функционально это или нет, а о том, что вся работа с последовательностями дизайнилась в функциональном стиле, а такой метод этот стиль нарушает. Иными словами, такой вариант противоречит дизайну языка, не важно какой сам по себе дизайн, функциональный или не очень. И там подробно разжевано почему.

2. Выразительности такой код не добавит, а наоборот, запутает и, плюс к этому, "добавляет семантику замыкания, потенциально внося тонкие изменения в жизненные циклы объектов." То есть, реально, такой метод ухудшает имеющийся оператор foreach, добавляя малопредсказуемые побочные эффекты.

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

Резюме: При кажущейся простоте, такой метод не предоставляя реальных преимуществ затрудняет понимание кода и способен привести к малопредсказуемым побочным эффектам.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[9]: LINQ & Except
От: _FRED_ Черногория
Дата: 11.06.09 13:22
Оценка:
Здравствуйте, IB, Вы писали:

ВВ>>Спасибо, я читаю по-английски.

IB>Видимо стоило, все-таки по русски. Ну ладно, я разжую. Аргументов там два, и оба отличаются от того, который ты нашел:

IB>1. Речь не о том, что функционально это или нет, а о том, что вся работа с последовательностями дизайнилась в функциональном стиле, а такой метод этот стиль нарушает. Иными словами, такой вариант противоречит дизайну языка, не важно какой сам по себе дизайн, функциональный или не очень. И там подробно разжевано почему.


При чём здесь "дизайн языка", когда речь о библиотечном методе? Слова были о дизайне библиотеки, о том, что данные метод плохо бы смотрелся среди других методов.

Я вижу слова "Я философски против предоставления такого метода по двум причинам." и не вижу "наличия". Да и в любом случае — мнение, высказаное в блоге является личным мнением Эрика или мнением команды, разрабатывавшей System.Core. Я не вижу ответа в тексте блога на вопрос "почему плохо в своём коде иметь такой метод". Всё, что можно понять — это рекомендации основанные на том, что "добавляет семантику замыкания" (1), "труднее понять" (2) и "труднее … отладить" (3).

По пунктам:

1. никто не заставляет пользоваться замыканиями, так что данное обоснование кажется надуманным. Ведь никто же не запрещает использовать замыкания и side effects в методах, передаваемых в Select или Where.

2. Это вопрос самый спорный. Например варианты здесь
Автор: _FRED_
Дата: 11.06.09
мне кажутся не трудными.

3. Мне гораздо несимпатичнее отладка такого кода:
Some1();

for(var x in yy) {
  // … сотня-другая итераций
}//fir

Some2();

когда меня не интересуют внутренности работы цикла (требуется от Some1 перейти к Some2). Отладчик не умеет "перепрагивать" через цикл и приходится ставить специальный breakpoint к Some2(); и перепрыгивать цикл самому.

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


Использование одной строчки там, где в другом случае нужно много больше. (здесь
Автор: _FRED_
Дата: 11.06.09
)

IB>Резюме: При кажущейся простоте, такой метод не предоставляя реальных преимуществ


Для стандартной библиотеки — да. Точно так же можно предать анафеме хелперы типа такого. Без ниже прекрасно можно обойтись. Но с ними лучше.

IB>…затрудняет понимание кода и способен привести к малопредсказуемым побочным эффектам.


Мне кажется, что этих эффектом можно добиться и без ForEach. Одновременно с этим, с ForEach можно этих же эффектов избежать. И причина возникновения эффектов не в ForEach, а в содержимом черепной коробки
Help will always be given at Hogwarts to those who ask for it.
Re[9]: LINQ & Except
От: Воронков Василий Россия  
Дата: 11.06.09 13:30
Оценка:
Здравствуйте, IB, Вы писали:

IB>Видимо стоило, все-таки по русски.


Знаешь, "по-русски" я бы тебе давно уже объяснил, что я думаю о подобных гайдлайнах — да боюсь забанят.

IB>1. Речь не о том, что функционально это или нет, а о том, что вся работа с последовательностями дизайнилась в функциональном стиле, а такой метод этот стиль нарушает.


*Вся* работа с последовательностями ли, с базой данных и пр. уж никак не может вестись в одном стиле, о чем уже так долго говорят большевики и с чем, видимо, придется смириться.
А в данном случае непонятно — откуда возникает требование этого функционального стиля? Если передо мной стоят задачи модификации или, не дай бог, появляются методы имеющие сохраняемое состояние — то причем здесь вообще функциональный стиль? И почему это должно быть функционально, если в действительности это не функционально ни на йоту?
Это мы только ForEach<> касаемся, а можно еще и рассмотреть всякие Aggregate<> — там ведь вообще ужас с этой точки зрения.

Да, и я уже приводил этот пример.
String.Replace — очень схожая задача с обсуждаемой здесь. И совершенно нефункционально. И при этом самая что ни на есть последовательность. В каком стиле предлагаете проводить замену?

IB>Иными словами, такой вариант противоречит дизайну языка, не важно какой сам по себе дизайн, функциональный или не очень. И там подробно разжевано почему.


Дизайну Шарпа противоречит императивный стиль?
Функциональному дизайну Линка, который здесь вообще не причем, противоречит императивный стиль?
Вам дали библиотеку со "спецэффектами" и теперь уже стиль у языка другой?

IB>2. Выразительности такой код не добавит, а наоборот, запутает и, плюс к этому, "добавляет семантику замыкания, потенциально внося тонкие изменения в жизненные циклы объектов." То есть, реально, такой метод ухудшает имеющийся оператор foreach, добавляя малопредсказуемые побочные эффекты.


То же самое можно сказать и про Where по сравнению с foreach.

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

IB>Резюме: При кажущейся простоте, такой метод не предоставляя реальных преимуществ затрудняет понимание кода и способен привести к малопредсказуемым побочным эффектам.

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