if (a == true)
От: Alekzander  
Дата: 03.09.24 09:04
Оценка: :))
Сразу оговорюсь, что вопрос больше не про философию программирования, а про психологию программистов.

Когда я давным-давно впервые увидел в коде сабж, то решил, что автор издевается (особенно без йода-сравнений). Но так действительно пишут, и нередко. В настоящий момент я думаю, что это глупый способ взять худшее из обоих миров.

О каких мирах речь? Есть такая практика — стараться использовать тип bool с большим разбором. Например, если есть упрощённая ("динозавровая") модель сервиса (или запущен, или нет — 50/50, состояния "запускается" и "глушится" принципиально не учитываются), надо не bool isStarted, а расписывать поле состояний (Started, NotStarted) в енаме. Логика тут такая, что если мы берём bool, то просто приспосабливаем другое, нерелевантное поле состояний только потому, что у него то же число элементов (два), а это, как вы понимаете, зашквар. Конечно, если правильно сформулировать имя (isStarted), то острота проблемы снижается, но всё равно "как-то, доктор, неаккуратненько". Особенно неаккуратненько это выглядит при рассматривании вызова функции с десятью bool'ами.

Конечно, так получается много лишней письни, и иногда строгостью жертвуют ради лаконичности.

Так вот, у меня появилась гипотеза, что те, кто пишет if (service.IsStarted == true), просто слышали звон. Останавливаются на половине, пытаются изображать строгость, при этом не расписывая состояния для каждого кейса.
I'm a sewer mutant, and my favorite authors are Edgar Allan Poo, H.G. Smells and George R.R. Martin.
Re: if (a == true)
От: kov_serg Россия  
Дата: 03.09.24 10:00
Оценка:
Здравствуйте, Alekzander, Вы писали:

A>Сразу оговорюсь, что вопрос больше не про философию программирования, а про психологию программистов.

if (a===true)

A>Когда я давным-давно впервые увидел в коде сабж, то решил, что автор издевается (особенно без йода-сравнений). Но так действительно пишут, и нередко. В настоящий момент я думаю, что это глупый способ взять худшее из обоих миров.

тогда лучше писать
if (a!=false)

A>О каких мирах речь? Есть такая практика — стараться использовать тип bool с большим разбором.

А кто сказал что а имеет тип bool ?

A>Так вот, у меня появилась гипотеза, что те, кто пишет if (service.IsStarted == true), просто слышали звон. Останавливаются на половине, пытаются изображать строгость, при этом не расписывая состояния для каждого кейса.

А если service.IsStarted это функция или перечисление. А так компилятор уматерит если что. А вообще это просто шаблонное поведение если в переменной такое значение то делаем то-то. А оптимизировать это дополнительное действие — лень. Более того тот кто писал вообще может быть с булевой алгеброй не знаком, и это ему совершенно не мешает.
Re[2]: if (a == true)
От: Alekzander  
Дата: 03.09.24 10:50
Оценка:
Здравствуйте, kov_serg, Вы писали:

A>>Сразу оговорюсь, что вопрос больше не про философию программирования, а про психологию программистов.

_>if (a===true)

Надо было уточнить, что речь про ЯП без === (я так понимаю, === имеет смысл только для нестрого-динамической типизации).

A>>Когда я давным-давно впервые увидел в коде сабж, то решил, что автор издевается (особенно без йода-сравнений). Но так действительно пишут, и нередко. В настоящий момент я думаю, что это глупый способ взять худшее из обоих миров.

_>тогда лучше писать
_>if (a!=false)

Это хуже йодинга: смысл перестановка меняет незначительно лишь, а инверсия страшная тут.

_>А кто сказал что а имеет тип bool ?


Если тип не bool, они в таких случаях пишут каст плюс == true.

A>>Так вот, у меня появилась гипотеза, что те, кто пишет if (service.IsStarted == true), просто слышали звон. Останавливаются на половине, пытаются изображать строгость, при этом не расписывая состояния для каждого кейса.

_>А если service.IsStarted это функция или перечисление. А так компилятор уматерит если что. А вообще это просто шаблонное поведение если в переменной такое значение то делаем то-то. А оптимизировать это дополнительное действие — лень. Более того тот кто писал вообще может быть с булевой алгеброй не знаком, и это ему совершенно не мешает.

Боюсь, не совсем понимаю. service.IsStarted это почти наверняка функция (аксессор). И?
I'm a sewer mutant, and my favorite authors are Edgar Allan Poo, H.G. Smells and George R.R. Martin.
Re: if (a == true)
От: scf  
Дата: 03.09.24 11:19
Оценка:
Здравствуйте, Alekzander, Вы писали:

A>Так вот, у меня появилась гипотеза, что те, кто пишет if (service.IsStarted == true), просто слышали звон. Останавливаются на половине, пытаются изображать строгость, при этом не расписывая состояния для каждого кейса.


Нет, просто считают, что так более понятно.
assert(something)
assert(!something)
assert(something == true)
assert(something == false)
Re[2]: if (a == true)
От: Alekzander  
Дата: 03.09.24 11:29
Оценка:
Здравствуйте, scf, Вы писали:

A>>Так вот, у меня появилась гипотеза, что те, кто пишет if (service.IsStarted == true), просто слышали звон. Останавливаются на половине, пытаются изображать строгость, при этом не расписывая состояния для каждого кейса.


scf>Нет, просто считают, что так более понятно.

scf>assert(something)
scf>assert(!something)
scf>assert(something == true)
scf>assert(something == false)

Раз ты не привёл пример something, пусть мы ассертируем запущенность сервиса, о которой речь шла выше.

assert(service.IsStarted) это лаконично.
assert(service.State == ServiceState.Started) это понятно. (Понятность проявляется не в assert'е, хотя это кому как, а когда мы позже передаём аргумент ServiceState.Started в какую-нибудь функцию вместо true).
assert(service.IsStarted == true) это ни туда ни сюда.
I'm a sewer mutant, and my favorite authors are Edgar Allan Poo, H.G. Smells and George R.R. Martin.
Re: if (a == true)
От: L.K. Марс  
Дата: 03.09.24 11:44
Оценка: :)
Ну, скажем, изначально было "if (a == 1)", потом сделали булевую переменную, а единицы поменяли на true (типа, так быстрее).

Ещё "а == true" заметнее, чем "а". Компилятору/интерпретатору зрительная заметность не важна, но человек, который будет читать код, увидит, что тут не просто какое-то мелкое "а", но целое "а == true", а значит, что это очень-очень важно, чтобы было именно true.
Re: if (a == true)
От: koenig  
Дата: 03.09.24 12:09
Оценка:
A>Когда я давным-давно впервые увидел в коде сабж, то решил, что автор издевается (особенно без йода-сравнений). Но так действительно пишут, и нередко.

это не про nullable?
Re[2]: if (a == true)
От: Alekzander  
Дата: 03.09.24 12:11
Оценка:
Здравствуйте, kov_serg, Вы писали:

A>>Сразу оговорюсь, что вопрос больше не про философию программирования, а про психологию программистов.

_>if (a===true)

Со второго раза я понял. Нахватались у динамиков, ты про это, да?
I'm a sewer mutant, and my favorite authors are Edgar Allan Poo, H.G. Smells and George R.R. Martin.
Re[2]: if (a == true)
От: Alekzander  
Дата: 03.09.24 12:11
Оценка:
Здравствуйте, koenig, Вы писали:

A>>Когда я давным-давно впервые увидел в коде сабж, то решил, что автор издевается (особенно без йода-сравнений). Но так действительно пишут, и нередко.


K>это не про nullable?


Нет, и не про operator bool.
I'm a sewer mutant, and my favorite authors are Edgar Allan Poo, H.G. Smells and George R.R. Martin.
Re: if (a == true)
От: yenik  
Дата: 03.09.24 13:22
Оценка:
Мои коллеги считают, что if (!service.IsStarted) — это нечитабельно, восклицательный знак не видно красными глазками.
Поэтому надо писать так: if (service.IsStarted == false).
А для консистентности также if (service.IsStarted == true)
И они реально так пишут. Я вначале удивлялся на код-ревью, но потом привык.
Мопед не мой, если что, отстаивать эту точку зрения не буду.
Re[2]: if (a == true)
От: · Великобритания  
Дата: 03.09.24 13:26
Оценка: +2 :)
Здравствуйте, yenik, Вы писали:

Y>Мои коллеги считают, что if (!service.IsStarted) — это нечитабельно, восклицательный знак не видно красными глазками.

Гы. Тогда уж if (true == service.IsStarted) чтобы уж по всем канонам.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[2]: if (a == true)
От: sergii.p  
Дата: 03.09.24 13:50
Оценка:
Здравствуйте, yenik, Вы писали:

Y>Мои коллеги считают, что if (!service.IsStarted) — это нечитабельно, восклицательный знак не видно красными глазками.

Y>Поэтому надо писать так: if (service.IsStarted == false).

эта рекомендация точно из какой-то книги. Возможно Фаулер "Рефакторинг". То есть коллеги не от больной фантазии это придумали. Да и отчасти согласиться можно — знак ! легко можно пропустить.
Re[2]: if (a == true)
От: m2user  
Дата: 03.09.24 14:06
Оценка: +1
Y>Мои коллеги считают, что if (!service.IsStarted) — это нечитабельно, восклицательный знак не видно красными глазками.
Вот так виднее: if (!(service.IsStarted))
Но если нужно, чтобы совсем виднее, то так:
bool serviceNotStarted = !service.IsStarted;
if (serviceNotStarted) { /*  */ }
Re[2]: if (a == true)
От: Alekzander  
Дата: 03.09.24 14:26
Оценка:
Здравствуйте, yenik, Вы писали:

Y>Мои коллеги считают, что if (!service.IsStarted) — это нечитабельно, восклицательный знак не видно красными глазками.

Y>Поэтому надо писать так: if (service.IsStarted == false).

По-моему, это свидетельствует в пользу моей гипотезы.
I'm a sewer mutant, and my favorite authors are Edgar Allan Poo, H.G. Smells and George R.R. Martin.
Re[3]: if (a == true)
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.09.24 15:40
Оценка: +1
Здравствуйте, Alekzander, Вы писали:
A>Это хуже йодинга: смысл перестановка меняет незначительно лишь, а инверсия страшная тут.
Смысл меняется, и очень-очень сильно. true обычно равно 0xFFFFFFFF.
При этом if(a) компилируется/интерпретируется как if(a!=0), подразумевая любое ненулевое значение.
В итоге, если в a попадает 42, то if(a == true) пройдёт мимо, а if(a != false) зайдёт внутрь. Как и if(a).
Так что, возможно пишет if(a == true) вовсе не идиот.
Может быть, a имеет тип "недоперечисления", которое организовано так, что -1 = started; 0 = stopped; 1 = starting; 2 = stopping; 16 = error. Для совместимости с совсем древним кодом, который написан для времён с двумя статусами сервиса, которые он проверял через if(!service->status).
А теперь нам нужен код, который убеждается, что сервис именно что запущен.

A>Если тип не bool, они в таких случаях пишут каст плюс == true.

Даже если тип bool, не всегда он сформирован честным образом из констант true, false, и булевых операций. Даже в дотнете я налетал (правда, из-за бага в моём же unsafe коде) на то, что булевая логика на SIMD дала не true, а non-false результат. В итоге, код с if(a) прекрасно работал, а вот тесты, которые сравнивали вычисленный массив булеанов с референс-значениями, фейлились.

A>Боюсь, не совсем понимаю. service.IsStarted это почти наверняка функция (аксессор). И?

Всё зависит от системы типов в языке.
Например, if(service.IsStarted) внезапно убеждается, что адрес этой функции ненулевой. И если ваш язык — не typescript, то не всякий компилятор будет вам намекать на отсутствие скобок.
А вот if(service.IsStarted == true) уже имеет некоторые шансы нарваться на no operator== defined for the arguments of type 'bool (*check)()' and 'bool'.
С другой стороны, это недостаточно каргокультно.
По классике, нужно писать вот так:
if(true == service.IsStarted())
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: if (a == true)
От: LaptevVV Россия  
Дата: 03.09.24 17:10
Оценка:
A>Так вот, у меня появилась гипотеза, что те, кто пишет if (service.IsStarted == true), просто слышали звон. Останавливаются на половине, пытаются изображать строгость, при этом не расписывая состояния для каждого кейса.
Эт ты глубоко копнул.
Все проще — у меня начинающие так пытаются писать, пока я им по рукам не дам.
После пи*лей — сразу как-то все понимают и начинают писать нормально
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[4]: if (a == true)
От: T4r4sB Россия  
Дата: 03.09.24 17:15
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

A>>Это хуже йодинга: смысл перестановка меняет незначительно лишь, а инверсия страшная тут.
S>Смысл меняется, и очень-очень сильно. true обычно равно 0xFFFFFFFF.

Это в каких языках?

S>Может быть, a имеет тип "недоперечисления", которое организовано так, что -1 = started; 0 = stopped; 1 = starting; 2 = stopping; 16 = error. Для совместимости с совсем древним кодом, который написан для времён с двумя статусами сервиса, которые он проверял через if(!service->status).

S>А теперь нам нужен код, который убеждается, что сервис именно что запущен.

if (service == STARTED)

А вот использовать тот факт, что битовое представление true совпало с битовм представлением STARTED — это говнокод
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re: if (a == true)
От: qqqqq  
Дата: 03.09.24 17:16
Оценка:
Разница между if (a == true) и if (a) в том, что в первом случае проверяется точно ли а равна константе true а во втором неравенство а нулю. Некоторым это важно. Скажем в C++ bool это тип и ему можно просвоить в коде только true или false a в C bool это байт (иногда BOOL) Tут можно присваивать вообще что угодно, компилятору похрен. Да, кстати, может этой переменной вообще никогда ничего не приваивали и значение ее — хрен знает (что в пределах байта). Тут даже строгая типизация C++ не поможет.

Я вообще у шибко строгих принято даже не if (a == true) а if (true == a).
Re: if (a == true)
От: vsb Казахстан  
Дата: 03.09.24 18:00
Оценка: :)
По-мне этот вопрос выеденного яйца не стоит.

Плохо, когда пишут if (size), к примеру, используя неявное приведение int к bool. Это прям очень плохо, я считаю.

Допустимо, когда пишут if (obj_ptr), используя неявное приведение указателя к bool. Я так не пишу, но беды в этом не вижу.

Писать if (isStarted) либо же if (isStarted == true) — вообще разницы не вижу. Я бы написал первый вариант, но второй так же прекрасно читается. Допускаю, что кому-то он читается лучше.

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

Городить enum-ы на ровном месте? Не знаю. Я обычно этого не делаю. Но если очень хочется — да ради бога...
Отредактировано 03.09.2024 18:01 vsb . Предыдущая версия .
Re[4]: if (a == true)
От: Alekzander  
Дата: 03.09.24 21:05
Оценка:
Здравствуйте, Sinclair, Вы писали:

A>>Это хуже йодинга: смысл перестановка меняет незначительно лишь, а инверсия страшная тут.

S>Смысл меняется, и очень-очень сильно. true обычно равно 0xFFFFFFFF.
S>При этом if(a) компилируется/интерпретируется как if(a!=0), подразумевая любое ненулевое значение.
S>В итоге, если в a попадает 42, то if(a == true) пройдёт мимо, а if(a != false) зайдёт внутрь. Как и if(a).
S>Так что, возможно пишет if(a == true) вовсе не идиот.
S>Может быть, a имеет тип "недоперечисления", которое организовано так, что -1 = started; 0 = stopped; 1 = starting; 2 = stopping; 16 = error. Для совместимости с совсем древним кодом, который написан для времён с двумя статусами сервиса, которые он проверял через if(!service->status).
S>А теперь нам нужен код, который убеждается, что сервис именно что запущен.

Я понял kov_serg'а так, что он предлагает в качестве альтернативы йода-сравнению (if (true == a)) инверсию (if (a != false)). Ведь при инверсии тоже нельзя нечаянно присвоить значение, перепутав = и == (помешает !), зато не придётся переставлять переменную в конец. Может, конечно, понял неправильно.

На это я ему возразил, что от перестановки при йода-сравнении (if (a == true)if (true == a)) смысл меняется незначительно (читается почти так же, выполняется одинаково), а вот предложенная инверсия — вещь страшная. Потому, что читается сильно иначе. После этого меня уже не волнует, насколько одинаково выполняется. Что показывает нам, как много проблем можно автоматически избежать, просто стремясь к выразительности.

A>>Если тип не bool, они в таких случаях пишут каст плюс == true.

S>Даже если тип bool, не всегда он сформирован честным образом из констант true, false, и булевых операций. Даже в дотнете я налетал (правда, из-за бага в моём же unsafe коде) на то, что булевая логика на SIMD дала не true, а non-false результат. В итоге, код с if(a) прекрасно работал, а вот тесты, которые сравнивали вычисленный массив булеанов с референс-значениями, фейлились.

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

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

A>>Боюсь, не совсем понимаю. service.IsStarted это почти наверняка функция (аксессор). И?

S>Всё зависит от системы типов в языке.
S>Например, if(service.IsStarted) внезапно убеждается, что адрес этой функции ненулевой. И если ваш язык — не typescript, то не всякий компилятор будет вам намекать на отсутствие скобок.
S>А вот if(service.IsStarted == true) уже имеет некоторые шансы нарваться на no operator== defined for the arguments of type 'bool (*check)()' and 'bool'.
S>С другой стороны, это недостаточно каргокультно.
S>По классике, нужно писать вот так:
S>
S>if(true == service.IsStarted())
S>


Теперь понял. Ну, смотря как делать свойства в языке-принимающем-адрес-за-true. Если их делать аналогично шарповским, через __declspec (поддерживается в clang с опцией компилятора -fdeclspec и MSVC), то перепутать нельзя, не скомпилируется:

https://gcc.godbolt.org/z/fdW74ocfG

Обе части 1 и 2 должны соответствовать.

(А по стандарту их надо делать через такую задницу, что лучше вообще не делать).

Глобальная же функция всего лишь даёт ворнинг. Что неприятно, да. То есть, как подстраховка от (забыли скобки) x (проигнорировали ворнинг) x (глобальная функция) x (сигнатура: возвращает bool, не имеет параметров) x (в норме всегда возвращает true, и не ловится при первом же запуске) добавление == true действительно помогает
I'm a sewer mutant, and my favorite authors are Edgar Allan Poo, H.G. Smells and George R.R. Martin.
Отредактировано 03.09.2024 21:10 Alekzander . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.