Много отрицаний
От: SiAVoL Россия  
Дата: 22.06.05 12:25
Оценка:
Ведущие собаковеды рекомендуют не использовать много отрицаний в условиях и уменьшать их, используя теоремы Моргана
Т.е. например код
if (str != null && str != "test")
    // ...

рекомендуется привести к
if ( !(str == null || str == "test") )
    // ...


ИМХО, первый вариант несколько более читаем — не равно нул и не равно строке "test". Все ясно и понятно. Смысл же второго (по крайней мере мне) уже не так очевиден.
Понятно, что когда условие сложное, то большое количество отрицаний реально замедляет понимание кода. Но зачастую классики приводят примеры аналогичные моему и говорят, что второй вариант лучше.
Это именно особенности моего восприятия, или классики ошибаются, или я что-то недопонимаю?
... << RSDN@Home 1.1.4 beta 7 rev. 463>>
Re: Много отрицаний
От: korzhik Россия  
Дата: 22.06.05 12:27
Оценка: +7
Здравствуйте, SiAVoL, Вы писали:

SAV>Ведущие собаковеды рекомендуют не использовать много отрицаний в условиях и уменьшать их, используя теоремы Моргана

SAV>Т.е. например код
SAV>
SAV>if (str != null && str != "test")
SAV>    // ...
SAV>

SAV>рекомендуется привести к
SAV>
SAV>if ( !(str == null || str == "test") )
SAV>    // ...
SAV>


SAV>ИМХО, первый вариант несколько более читаем — не равно нул и не равно строке "test". Все ясно и понятно. Смысл же второго (по крайней мере мне) уже не так очевиден.


Согласен. Первый вариант более читабельный
Re: Много отрицаний
От: Курилка Россия http://kirya.narod.ru/
Дата: 22.06.05 12:31
Оценка:
Здравствуйте, SiAVoL, Вы писали:

SAV>Ведущие собаковеды рекомендуют не использовать много отрицаний в условиях и уменьшать их, используя теоремы Моргана

...
А, если не секрет, кто они эти загадочные "ведущие собаковеды", проповедующие сие?
Re: Много отрицаний
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 22.06.05 12:38
Оценка: 12 (1) +2
Здравствуйте, SiAVoL, Вы писали:

SAV>Ведущие собаковеды рекомендуют не использовать много отрицаний в условиях и уменьшать их, используя теоремы Моргана

SAV>Т.е. например код
SAV>
SAV>if (str != null && str != "test")
SAV>    // ...
SAV>


Имхо, много отрицаний было бы в случае:
if( !(str == null) && !( str == "test" ) )
    // ...


А так это всего лишь несколько неравенств.

... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Много отрицаний
От: xvost Германия http://www.jetbrains.com/company/people/Pasynkov_Eugene.html
Дата: 22.06.05 12:45
Оценка: +2 :))
Здравствуйте, korzhik, Вы писали:

K>Согласен. Первый вариант более читабельный


Более того, первый вариант еще и в общем случае быстрее работает
С уважением, Евгений
JetBrains, Inc. "Develop with pleasure!"
Re[2]: Много отрицаний
От: korzhik Россия  
Дата: 22.06.05 12:46
Оценка:
Здравствуйте, eao197, Вы писали:

>Имхо, много отрицаний было бы в случае:

E>
E>if( !(str == null) && !( str == "test" ) )
E>    // ...
E>


E>А так это всего лишь несколько неравенств.


E>)


согласен, пример в начальном посте выбран неудачно
Re: Много отрицаний
От: GlebZ Россия  
Дата: 22.06.05 12:57
Оценка:
Здравствуйте, SiAVoL, Вы писали:

SAV>Ведущие собаковеды рекомендуют не использовать много отрицаний в условиях и уменьшать их, используя теоремы Моргана

SAV>Т.е. например код
SAV>
SAV>if (str != null && str != "test")
SAV>    // ...
SAV>

SAV>рекомендуется привести к
SAV>
SAV>if ( !(str == null || str == "test") )
SAV>    // ...
SAV>


SAV>ИМХО, первый вариант несколько более читаем — не равно нул и не равно строке "test". Все ясно и понятно. Смысл же второго (по крайней мере мне) уже не так очевиден.

SAV>Понятно, что когда условие сложное, то большое количество отрицаний реально замедляет понимание кода. Но зачастую классики приводят примеры аналогичные моему и говорят, что второй вариант лучше.
SAV>Это именно особенности моего восприятия, или классики ошибаются, или я что-то недопонимаю?
Хомяковеды таким не заморачиваются.
И вообще, на основании чего такие выводы? Кто эти собаководы?

С уважением, Gleb/
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re: Много отрицаний
От: BlackBox Россия ---
Дата: 22.06.05 13:43
Оценка:
Здравствуйте, SiAVoL, Вы писали:

// скип

У меня есть такой код
if (nat_enabled && !(nat_except && nat_addr == ApplyMask(ip_dst, nat_mask))){}


и помоему он более читабелен, чем
if (nat_enabled && (!nat_except || nat_addr != ApplyMask(ip_dst, nat_mask))){}
Re: Много отрицаний
От: Павел Кузнецов  
Дата: 22.06.05 15:56
Оценка: 12 (1) +1
SiAVoL,

> Ведущие собаковеды рекомендуют не использовать много отрицаний в условиях и уменьшать их, используя теоремы Моргана


Обычно речь идет о множественных отрицаниях, т.е. об отрицаниях отрицаний:
if ( !( !(str == null) && str != "test" ) )
     // ...
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: Много отрицаний
От: Airat Burganov Россия http://www.burganov.com
Дата: 22.06.05 21:03
Оценка: 9 (1) +4
Здравствуйте, SiAVoL, Вы писали:

SAV>Ведущие собаковеды рекомендуют не использовать много отрицаний в условиях и уменьшать их, используя теоремы Моргана


Кроме того, ведущие собаковеды советуют использовать рефакторинги
1) Декомпозиция условного оператора.
2) Консолидация условного выражения
3) Консолидация дублирующихся условных фрагментов
4) Замена вложенных условных операторов граничным оператором


Фаулер — форева!
Re[2]: Много отрицаний
От: SiAVoL Россия  
Дата: 23.06.05 07:25
Оценка:
Здравствуйте, eao197, Вы писали:

E>Имхо, много отрицаний было бы в случае:

E>
E>if( !(str == null) && !( str == "test" ) )
E>    // ...
E>

вы знаете, я тут подумал, поперебирал в памяти оти самые рекомендации (к сожалению ссылок привести не могу) и понял что я видимо не правильно их понял. Скорее всего действительно речь шла о
if (!firstCondition && !secondCondition)
... << RSDN@Home 1.1.4 beta 7 rev. 463>>
Re[3]: Много отрицаний
От: qxWork Голландия http://www.jetbrains.com/company/people/Coox_Sergey.html
Дата: 23.06.05 10:33
Оценка:
X>Более того, первый вариант еще и в общем случае быстрее работает
ровно на 1 такт ))
Re: Много отрицаний
От: 0xDEADBEEF Ниоткуда  
Дата: 27.06.05 13:07
Оценка:
Hello, SiAVoL!
You wrote on Wed, 22 Jun 2005 12:25:55 GMT:

S> Ведущие собаковеды рекомендуют не использовать много отрицаний в

S> условиях и уменьшать их, используя теоремы Моргана Т.е. например код
S>
 S> if (str != null && str != "test")
 S>  // ...
 S>

S> рекомендуется привести к
S>
 S> if ( !(str == null || str == "test") )
 S>  // ...
 S>


S> ИМХО, первый вариант несколько более читаем — не равно нул и не равно

S> строке "test".

Не знаю как на C#, а на C эти два варианта одинаковы по производительности.
Что же касается нюансов обобщенного программирования, то имеет смысл предпочесть 2-й
Смысл в том что тип к которому принадлежит str может не иметь оператора '!=' и иметь оператор '=='.
Конечно, концепция 'Equality Comparable' требует наличия и того и другого оператора,
но зачастую лентяи-программисты ограничиваются реализацие только оператора '=='...
Posted via RSDN NNTP Server 1.9
__________
16.There is no cause so right that one cannot find a fool following it.
Re[2]: Много отрицаний
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 27.06.05 13:13
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

DEA>Смысл в том что тип к которому принадлежит str может не иметь оператора '!=' и иметь оператор '=='.

DEA>Конечно, концепция 'Equality Comparable' требует наличия и того и другого оператора,
DEA>но зачастую лентяи-программисты ограничиваются реализацие только оператора '=='...

Не лентяи программисты предпочитают определять всего один оператор '<'. А затем через него выводить и равенство, и неравенство и т.д.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: Много отрицаний
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 27.06.05 14:07
Оценка: 1 (1) +1
Здравствуйте, SiAVoL, Вы писали:

SAV>
SAV>if (str != null && str != "test")
SAV>    // ...
SAV>

SAV>рекомендуется привести к
SAV>
SAV>if ( !(str == null || str == "test") )
SAV>    // ...
SAV>


Я бы рекомендовал код типа таких:
if( (pointer != null) && (используем выражения с pointer зная что он точно не null) )

if( (array != null) && (array.Length >= N) && (используем выражения с array зная что он точно не null и что его длина точно >= N) )


не превращать "тождественными" преобразованиями ни во что другое. Проверка выражений идет слева на право и если на каком-то шаге результат становится известным, то дальнейшая проверка "хвоста" не осуществляется.
Re[3]: Много отрицаний
От: 0xDEADBEEF Ниоткуда  
Дата: 27.06.05 15:31
Оценка: :)
Здравствуйте, eao197, Вы писали:

E>Не лентяи программисты предпочитают определять всего один оператор '<'. А затем через него выводить и равенство, и неравенство и т.д.


Неправда. Лентяи не знают что через '<' можно вывести равенство .
А те кто знает, знает также и тот факт что вывод равенства через '<' требует двух сравнений вместо одного, а этого программистская совесть так легко не позволит.
__________
16.There is no cause so right that one cannot find a fool following it.
Re[4]: Много отрицаний
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 27.06.05 15:38
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

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


E>>Не лентяи программисты предпочитают определять всего один оператор '<'. А затем через него выводить и равенство, и неравенство и т.д.


DEA>Неправда. Лентяи не знают что через '<' можно вывести равенство .

DEA>А те кто знает, знает также и тот факт что вывод равенства через '<' требует двух сравнений вместо одного, а этого программистская совесть так легко не позволит.

А как же STL?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: Много отрицаний
От: 0xDEADBEEF Ниоткуда  
Дата: 27.06.05 15:51
Оценка:
Hello, eao197!
You wrote on Mon, 27 Jun 2005 15:38:44 GMT:

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


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


E>>> Не лентяи программисты предпочитают определять всего один оператор

E>>> '<'. А затем через него выводить и равенство, и неравенство и т.д.

DEA>> Неправда. Лентяи не знают что через '<' можно вывести равенство .

DEA>> А те кто знает, знает также и тот факт что вывод равенства через '<'
DEA>> требует двух сравнений вместо одного, а этого программистская совесть
DEA>> так легко не позволит.

e> А как же STL?

Ты это про rel_ops? Так там мухи и котлеты подаются отдельно. В том смысле что
'!=' реализуется через '==' а отношения порядка — через '<'. И это, кстати, требуется стандартом (20.2.1)
Posted via RSDN NNTP Server 1.9
__________
16.There is no cause so right that one cannot find a fool following it.
Re[6]: Много отрицаний
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 27.06.05 15:56
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

DEA>>> Неправда. Лентяи не знают что через '<' можно вывести равенство .

DEA>>> А те кто знает, знает также и тот факт что вывод равенства через '<'
DEA>>> требует двух сравнений вместо одного, а этого программистская совесть
DEA>>> так легко не позволит.

e>> А как же STL?

DEA>Ты это про rel_ops? Так там мухи и котлеты подаются отдельно. В том смысле что
DEA>'!=' реализуется через '==' а отношения порядка — через '<'. И это, кстати, требуется стандартом (20.2.1)

Не, я про то, что для использование своих классов в set или map не нужно определять ничего, кроме '<'.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: Много отрицаний
От: 0xDEADBEEF Ниоткуда  
Дата: 27.06.05 16:10
Оценка:
Hello, eao197!
You wrote on Mon, 27 Jun 2005 15:56:23 GMT:

e> Не, я про то, что для использование своих классов в set или map не нужно

e> определять ничего, кроме '<'.
Эти контейнеры являются упорядоченными. Для того чтобы они были такими, достаточно предиката порядка — по умолчанию std::less, который в свою очередь использует '<'.

ЗЫ. А вот "неупорядоченные" контейнеры (из TR1) unordered_(map|set) требуют чтобы были определены и предикаты эквивалентности и предикаты порядка...
Posted via RSDN NNTP Server 1.9
__________
16.There is no cause so right that one cannot find a fool following it.
Re[4]: Много отрицаний
От: Павел Кузнецов  
Дата: 27.06.05 17:31
Оценка:
0xDEADBEEF,

> E> Не лентяи программисты предпочитают определять всего один оператор '<'. А затем через него выводить и равенство, и неравенство и т.д.


> Неправда. Лентяи не знают что через '<' можно вывести равенство .


Более того, нелентяи знают, что есть разница между отношением эквивалентности, устанавливаемым двумя вызовами <, и равенством/неравенством, устанавливаемыми одним вызовом ==/!=.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[5]: Много отрицаний
От: 0xDEADBEEF Ниоткуда  
Дата: 27.06.05 19:32
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

>> Неправда. Лентяи не знают что через '<' можно вывести равенство .


ПК>Более того, нелентяи знают, что есть разница между отношением эквивалентности, устанавливаемым двумя вызовами <, и равенством/неравенством, устанавливаемыми одним вызовом ==/!=.


Ну-ка, ну-ка, с этого места и поподробнее. В чем же будет разница между отношениями эквивалентности и порядка при следующих условиях: если (a < b), то (a != b); если (b < a), то (a != b); ? Естественно, подразумевается что отношения эквивалентности коммутативны, а отношения порядка — нет.
__________
16.There is no cause so right that one cannot find a fool following it.
Re[6]: Много отрицаний
От: Павел Кузнецов  
Дата: 27.06.05 21:23
Оценка:
0xDEADBEEF,

> ПК>Более того, нелентяи знают, что есть разница между отношением эквивалентности, устанавливаемым двумя вызовами <, и равенством/неравенством, устанавливаемыми одним вызовом ==/!=.


> Ну-ка, ну-ка, с этого места и поподробнее.


Если есть некоторый предикат, задающий порядок, то далеко не обязательно из (a < b) == false && (b < a) == false следует (a == b) == true. Например, предикат, задающий case insensitive упорядочивание строк при case sensitive сравнении. И наоборот. Допустим, для некоторого класса чисел с плавающей точкой операция сравнения работает с учетом epsilon. В этом случае для двух очень близких чисел (с разницей в пределах epsilon) второе условие будет верно, а первое — нет.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[7]: Много отрицаний
От: 0xDEADBEEF Ниоткуда  
Дата: 28.06.05 11:46
Оценка:
Hello, Павел!
You wrote in conference rsdn.philosophy on Mon, 27 Jun 2005 21:23:45 GMT:

ПК> 0xDEADBEEF,


ПК>>> Более того, нелентяи знают, что есть разница между отношением эквивалентности, устанавливаемым двумя вызовами <, и

ПК>>> равенством/неравенством, устанавливаемыми одним вызовом ==/!=.

ПК>> Ну-ка, ну-ка, с этого места и поподробнее.


ПК> Если есть некоторый предикат, задающий порядок, то далеко не обязательно из

ПК> (a < b) == false && (b < a) == false следует (a == b) == true.
Это так в текущем стандарте STL. Там понятия эквивалентности и порядка не связаны.
То есть, формально ты прав.

Впрочем, остается еще один вопрос: Ist das gut? В смысле хорошо ли есть такое размежевание с математическими понятиями порядка и эквивалентности?

ЗЫ. В какой-то книжке (уж не Design & Evoloution of C++?) я читал по поводу стандартизации упорядоченных контейнеров.
Там приводились дискусии о критериях упорядочивания. Рассматривались предикаты 'bool operator<' и 'int compare(rhs)' аналогичный strcmp(). А вот rationale почему остановились на том на чем остановились я, увы, не помню.
Posted via RSDN NNTP Server 1.9
__________
16.There is no cause so right that one cannot find a fool following it.
Re: Много отрицаний
От: Ranger_XL  
Дата: 29.06.05 10:19
Оценка:
SAV>
SAV>if (str != null && str != "test")
SAV>    // ...
SAV>

SAV>рекомендуется привести к
SAV>
SAV>if ( !(str == null || str == "test") )
SAV>    // ...
SAV>


ИМХО, единственный случай, когда 2-ой вариант может быть предпочтительнее первого, если нас интересует постусловие завершения цикла.

while ( !(str == null || str == "test") ) {
   ...
}
// здесь у нас str == null || str == "test"
Re[4]: Много отрицаний
От: FDSC Россия consp11.github.io блог
Дата: 30.06.05 08:09
Оценка:
Здравствуйте, qxWork, Вы писали:

X>>Более того, первый вариант еще и в общем случае быстрее работает

W>ровно на 1 такт ))


Не фига.

1. Первый вариант в общем работает столько же, сколько и второй. Отрицание в самом операторе не реализуется машинной командой отрицания.

2. Второй вариант может сработать быстрее ровно на 1 такт. Если проверка первого значения сразу даст true, а компилятор работает с настройкой быстрого вычисления булевских выражений.
Re[2]: Много отрицаний
От: FDSC Россия consp11.github.io блог
Дата: 30.06.05 08:15
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

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


SAV>>
SAV>>if (str != null && str != "test")
SAV>>    // ...
SAV>>

SAV>>рекомендуется привести к
SAV>>
SAV>>if ( !(str == null || str == "test") )
SAV>>    // ...
SAV>>


СГ>Я бы рекомендовал код типа таких:

СГ>
СГ>if( (pointer != null) && (используем выражения с pointer зная что он точно не null) )
СГ>

СГ>
СГ>if( (array != null) && (array.Length >= N) && (используем выражения с array зная что он точно не null и что его длина точно >= N) )
СГ>


СГ>не превращать "тождественными" преобразованиями ни во что другое. Проверка выражений идет слева на право и если на каком-то шаге результат становится известным, то дальнейшая проверка "хвоста" не осуществляется.


Можно очень, очень, очень не хорошо попасть с настройками компилятора.

Впрочем я не против этого.
Re: Много отрицаний
От: ukshish  
Дата: 30.06.05 08:23
Оценка:
Здравствуйте, SiAVoL, Вы писали:

SAV>Ведущие собаковеды рекомендуют не использовать много отрицаний в условиях и уменьшать их, используя теоремы Моргана

SAV>Т.е. например код
SAV>
SAV>if (str != null && str != "test")
SAV>    // ...
SAV>

SAV>рекомендуется привести к
SAV>
SAV>if ( !(str == null || str == "test") )
SAV>    // ...
SAV>


SAV>ИМХО, первый вариант несколько более читаем — не равно нул и не равно строке "test". Все ясно и понятно. Смысл же второго (по крайней мере мне) уже не так очевиден.

SAV>Понятно, что когда условие сложное, то большое количество отрицаний реально замедляет понимание кода. Но зачастую классики приводят примеры аналогичные моему и говорят, что второй вариант лучше.
SAV>Это именно особенности моего восприятия, или классики ошибаются, или я что-то недопонимаю?

Может, речь идёт об операторе "!". Оператор "!=" ничуть не хуже оператора "==". В итоге второй вариант как раз и содержит лишний "!".
Re[2]: Много отрицаний
От: FDSC Россия consp11.github.io блог
Дата: 30.06.05 09:02
Оценка:
Здравствуйте, ukshish, Вы писали:

U>Может, речь идёт об операторе "!". Оператор "!=" ничуть не хуже оператора "==". В итоге второй вариант как раз и содержит лишний "!".


Читать весь форум надо. Уже в самой первой ветке было сказано, что пример супер неудачный, а автор неправильно понял рекомендации
Re[2]: Много отрицаний
От: Oleg A. Bachin Украина  
Дата: 05.07.05 12:45
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Я бы рекомендовал код типа таких:

СГ>
СГ>if( (pointer != null) && (используем выражения с pointer зная что он точно не null) )
СГ>

СГ>
СГ>if( (array != null) && (array.Length >= N) && (используем выражения с array зная что он точно не null и что его длина точно >= N) )
СГ>


СГ>не превращать "тождественными" преобразованиями ни во что другое. Проверка выражений идет слева на право и если на каком-то шаге результат становится известным, то дальнейшая проверка "хвоста" не осуществляется.


помнится в свое время я был сильно удивлен, что в IB это не так
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Best regards,
Oleg A. Bachin
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.