Apakah pernah ada syarat untuk memiliki efek samping? [Tutup]

10

Saya mengambil kursus struktur data menengah sebagai prasyarat untuk masuk ke program MS MS di Universitas yang pernah didengar semua orang di Amerika. Satu baris kode yang ditulis di kelas menarik perhatian saya:

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

Ini tidak akan memberikan ulasan kode di tempat kerja saya. Jika Anda menulis kode seperti ini dalam sebuah wawancara, ini akan menjadi serangan signifikan terhadap Anda. (Selain menjadi bersyarat dengan efek samping, itu menjadi pintar dengan mengorbankan kejelasan.)

Bahkan, saya belum pernah melihat persyaratan dengan efek samping, dan Googling juga tidak banyak muncul. Siswa lain tetap tinggal di belakang kelas untuk bertanya tentang hal itu, jadi saya bukan satu-satunya yang menganggap ini aneh. Tetapi profesor itu bersikeras bahwa ini adalah kode yang dapat diterima, dan bahwa dia akan menulis sesuatu seperti itu di tempat kerja. (Pekerjaan FT-nya adalah sebagai SWE Kepala Sekolah di sebuah perusahaan yang Anda semua pernah dengar.)

Saya tidak bisa membayangkan dunia di mana garis kode ini dapat diterima, apalagi diinginkan. Apakah aku salah? Apakah ini ok? Bagaimana dengan kasus yang lebih umum: bersyarat dengan efek samping? Apakah semua itu baik-baik saja?

rianjs
sumber
7
Garis itu harus dilepaskan dari orbit. Dua kali untuk ukuran yang baik.
Blrfl
8
Nit: Pipa tunggal (bilah vertikal) adalah bitwise - atau dalam sebagian besar bahasa, daripada "atau" yang logis. Itu tidak korsleting jika sisi kiri benar. Karena persyaratan ini memiliki efek samping di sisi kanan, itu membuat perbedaan besar dalam hasilnya.
Jonathan Eunice
2
Ada idiom yang digunakan dalam berbagai bahasa yang akan masuk dalam kategori ini, tetapi karena mereka "terkenal" atau "normal" tidak menimbulkan masalah. Baris dalam pertanyaan sepertinya tidak termasuk dalam kategori penggunaan idiomatis jadi saya akan menghindarinya.
Jaydee
2
@ JonathanEunice, ya, beberapa orang bingung tentang evaluasi arus pendek. Bukan kesalahan ketik pada bagian saya.
rianjs
5
Lihatlah sisi baiknya. Anda sekarang tahu satu perusahaan lagi di mana Anda TIDAK ingin wawancara.
John R. Strohm

Jawaban:

23

Ada satu efek samping semi-kondisional yang saya pikir tidak apa-apa:while(iter.MoveNext())

Yang mengatakan, saya pikir ini sebagian besar jatuh ke dalam kategori " tidak pernah merupakan kualifikasi yang sangat besar". Saya bisa memikirkan beberapa kasus langka di mana saya melihatnya dapat diterima, tetapi secara umum ini keji dan harus dihindari.

Saya juga tidak bisa memikirkan skenario di mana garis tertentu itu dapat diterima, tetapi saya juga tidak bisa memikirkan skenario di mana garis tertentu akan berguna , sehingga sulit untuk membayangkan konteksnya.

Telastyn
sumber
Itu hanya garis pembuangan dalam metode selama kelas. Itu tidak dimaksudkan untuk melakukan sesuatu yang bermanfaat.
rianjs
4
Secara ekuivalen, while(v = *p++)pemindaian gaya C / C ++ melalui array tanpa-penghentian (misalnya string C) cukup umum dan diterima secara luas.
Phil Miller
3
Saya sering menganggap pengulangan kondisional formulir while(c = input.read() != '\n')sebagai idiomatis.
1
Mungkin ada beberapa idiom umum yang dapat diterima, tetapi jelas "menjadi pintar dengan mengorbankan kejelasan" jatuh di perkemahan PERNAH.
Julia Hayward
Saya benar-benar lupa tentang iter.MoveNext (). Kasus yang sepenuhnya masuk akal untuk bersyarat memiliki efek samping. Terima kasih!
rianjs
8

Di dunia saya, membaca dari memori dapat dianggap sebagai efek samping (misalnya memori dipetakan IO).

Sekarang, pertimbangkan hal berikut:

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

Dan bandingkan dengan:

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

Apakah menghindari efek samping (baca) dalam kondisi membantu keterbacaan; atau apakah itu hanya duplikat kode dan tambahkan kekacauan?

Tidak masalah jika suatu kondisi memiliki efek samping (jika itu membuat kode tersebut kurang terbaca) dan itu juga OK untuk suatu kondisi memiliki efek samping (jika itu membuat kode lebih mudah dibaca). Faktor kuncinya adalah "keterbacaan". Yang lainnya adalah aturan yang dibuat oleh orang bodoh dalam upaya yang salah arah untuk meningkatkan keterbacaan (sementara sering memiliki efek sebaliknya).

Brendan
sumber
3

Seperti biasa dengan pertanyaan-pertanyaan seperti itu, ini masalah derajat. Jika ada bukti nyata bahwa efek samping apa pun dalam ifekspresi selalu mengarah pada kode yang lebih buruk, maka tidak sah untuk membuat ekspresi itu. Bahasa desainer mungkin ideosyncratic, manusia bisa salah, tapi mereka tidak yang bodoh.

Yang mengatakan, apa saja contoh efek samping yang dibenarkan dalam suatu if? Misalnya, anggap Anda diharuskan secara hukum untuk mencatat semua dan semua akses ke properti Pentitas Euntuk tujuan audit. (Bayangkan Anda bekerja di pabrik pengayaan uranium, dan ada kontrol hukum yang sangat ketat tentang apa yang diizinkan kode Anda dan bagaimana seharusnya melakukannya.) Lalu, setiap ifyang memeriksa properti itu akan menyebabkan efek samping dari log audit diperpanjang.

Itu masalah lintas sektoral yang cukup jelas, itu tidak memengaruhi alasan Anda tentang status program (sangat banyak), dan Anda dapat menerapkannya sehingga sama sekali tidak terlihat dan tidak mengganggu ketika Anda meninjau baris dengan if(disembunyikan) di accessor, atau bahkan lebih baik melalui AOP). Saya akan mengatakan itu adalah kasus efek samping yang cukup jelas yang tidak menjadi perhatian. Situasi serupa mungkin dibayangkan ketika Anda hanya ingin menghitung eksekusi cabang untuk tujuan pembuatan profil, dll.

Semakin banyak keadaan yang meringankan ini hilang, orang asing yang akan menjadi konstruk. Jika jenis loop tertentu (mis. if((c = getc()) == 'x') { quit(); }Terkenal dan diterima oleh komunitas bahasa, maka itu jauh lebih sedikit masalah daripada ketika Anda menciptakannya secara spontan, dll. Baris contoh Anda kurang dari standar itu, tapi saya bisa membayangkan banyak, banyak lebih mengerikan yang saya bahkan tidak akan ketik, mereka begitu mengerikan.

Kilian Foth
sumber
2

Walaupun kode ini benar-benar bau, ia memiliki keuntungan karena lebih sederhana (dan mungkin lebih cepat jika Anda tidak memiliki kompilator pengoptimal yang baik) daripada yang setara if (a > 33 | b < 54) {b++; ...} else b++;

tetapi tentu saja dimungkinkan untuk mengoptimalkannya sebagai berikut (tapi hati-hati! yang satu ini memiliki perilaku berbeda jika meluap!): b++; if (a > 33 | b < 53) {...}

Franki
sumber