Чи коли-небудь добре, що за умови, що має побічні ефекти? [зачинено]


10

Я беру курс проміжних структур даних як передумову для вступу до програми MS MS в університеті, про який чули всі в Америці. Один рядок коду, написаний у класі, привернув мене до уваги:

if (a > 33 | b++ < 54) {...}

Це не пройшло перевірку коду на моєму робочому місці. Якщо ви написали такий код в інтерв'ю, це було б суттєвим страйком проти вас. (Окрім того, що є умовною з побічними ефектами, вона розумна за рахунок ясності.)

Насправді я ніколи не бачив умовних побічних ефектів, і Гуглінг теж не сильно з'являється. Ще один студент залишився позаду після заняття, щоб запитати про це теж, тож я не єдиний, хто вважав це дивним. Але професор був досить прихильний, що це прийнятний код і що він щось подібне буде писати на роботі. (Його робота в галузі фінансів - це головний SWE в компанії, про яку ви всі чули.)

Я не можу уявити собі світ, у якому ця лінія коду була б колись прийнятною, не кажучи вже про бажаною. Я помиляюся? Чи це добре? А як щодо більш загального випадку: кондиціонування з побічними ефектами? З цим колись все гаразд?


7
Ця лінія повинна бути виведена з орбіти. Двічі на добру міру.
Blrfl

8
Ніт: Одинарна труба (вертикальна смуга) є побітною або в більшості мов, а не логічним "чи". Це не має короткого замикання, якщо ліва частина вірна. Оскільки ця умова має побічні ефекти з правого боку, це робить дуже велику різницю в результаті.
Джонатан Юніс

2
Існують ідіоми, які використовуються в різних мовах, які підпадали б до цієї категорії, але оскільки вони "добре відомі" або "нормальні", не створюють проблем. Рядок у питанні, схоже, не входить у категорію ідіоматичного використання, тому я б цього не уникав.
Jaydee

2
@JonathanEunice, так, деякі люди були збентежені щодо оцінки короткого замикання. Не друкарня з мого боку.
rianjs

5
Подивіться на світлу сторону. Тепер ви знаєте ще одну компанію, в якій НЕ хочете брати інтерв'ю.
Джон Р. Стром

Відповіді:


23

Є один напівумовний побічний ефект, який я можу вважати, що це нормально:while(iter.MoveNext())

Однак, я думаю, що це в основному підпадає під категорію " ніколи не є дійсно великим класифікатором". Я можу подумати про декілька рідкісних випадків, коли я бачив це прийнятним, але загалом це мерзенно і цього потрібно уникати.

Я також не можу придумати сценарій, коли цей конкретний рядок був би прийнятним, але я також не можу придумати сценарій, коли цей конкретний рядок був би корисним , тому важко уявити, в якому контексті він знаходиться.


Це був просто викинутий рядок у методі під час уроку. Це не було наміром робити щось корисне.
rianjs

4
В еквівалентному порядку while(v = *p++)сканування стилів C / C ++ через масив, що закінчується нулем (наприклад, рядок C), є досить поширеними та широко прийнятими.
Філ Міллер

3
Я часто вважав умови циклу форми while(c = input.read() != '\n')досить ідіоматичними.

1
Можливо, є декілька загальноприйнятих ідіом, але явно «розумний за рахунок ясності» потрапляє у НІКОЛИ табір.
Джулія Хейвард

Я повністю забув про iter.MoveNext (). Цілком розумний випадок для умовного, що має побічний ефект. Дякую!
rianjs

8

У моєму світі читання з пам’яті може вважатися побічним ефектом (наприклад, IOP, що відображається на пам'яті).

Тепер розглянемо наступне:

    while( ( *memory_mapped_device_status_register & READY_FLAG) == 0) {
       // Wait
    }

І порівняйте:

    status = *memory_mapped_device_status_register;
    while( ( status & READY_FLAG) == 0) {
        // Wait
        status = *memory_mapped_device_status_register;
    }

Чи уникало побічного ефекту (прочитаного) у стані сприяє читабельності; чи це просто дублював код і додав безлад?

Невірно, щоб стан мав побічні ефекти (якщо це робить код менш читабельним), а також нормально, щоб стан мав побічні ефекти (якщо це робить код більш читабельним). Ключовий фактор - «читабельність». Все інше - це правила, створені дурнями в помилковій спробі поліпшити читабельність (хоча часто мають протилежний ефект).


3

Як завжди з такими питаннями, це питання ступеня. Якщо були б однозначні докази того, що будь-який побічний ефект у ifвиразі завжди призводив до гіршого коду, тоді не було б законним створювати ці вирази. Мовні дизайнери можуть бути ідеосинкратичними, помилковими людьми, але вони не такі дурні.

Однак, які приклади виправданих побічних ефектів всередині if? Наприклад, припустимо, що вам потрібно юридично записати весь та будь-який доступ до майна Pсуб'єкта господарювання Eдля аудиторських цілей. (Уявіть собі , що ви працюєте в збагаченню урану заводу, і є дуже строгі заходи правового контролю , про те , що ваш код дозволено робити і як це повинно зробити це.) Тоді будь-який , ifщо перевіряє , що властивість буде викликати побічний ефект Розширюється журнал аудиту.

Це досить чітка наскрізна стурбованість, це не впливає на ваші міркування про стан програми (дуже багато), і ви можете реалізувати це так, щоб воно було абсолютно непомітним і не відволікало увагу при перегляді рядка з if(прихованим подалі від аксесуара, а ще краще через AOP). Я б сказав, що це досить очевидний випадок побічного ефекту, який не викликає особливих проблем. Подібні ситуації можна уявити, коли ви просто хочете порахувати виконання філій для цілей профілювання тощо.

Чим більше ці пом'якшувальні обставини зникають, тим більш дивною буде конструкція. Якщо певний тип циклу (наприклад if((c = getc()) == 'x') { quit(); }, добре відомий і прийнятий мовною спільнотою, це набагато менше проблем, ніж коли ви винаходите його спонтанно і т. Д. Ваш приклад рядка не відповідає цьому стандарту, але я міг би уявити багато, багато більш жахливі, які я навіть не набираю, вони такі жахливі.


2

Хоча насправді смердючий код, він має перевагу в тому, що він простіший (а може бути і швидший, якщо у вас немає хорошого оптимізуючого компілятора), ніж еквівалент if (a > 33 | b < 54) {b++; ...} else b++;

але, звичайно, можна оптимізувати це до наступного (але будьте уважні! у цього є інша поведінка у разі переповнення!): b++; if (a > 33 | b < 53) {...}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.