Katakanlah saya memiliki kondisi boolean a AND b OR c AND d
dan saya menggunakan bahasa yang AND
memiliki preseden operasi urutan yang lebih tinggi daripada OR
. Saya bisa menulis baris kode ini:
If (a AND b) OR (c AND d) Then ...
Tapi sungguh, itu setara dengan:
If a AND b OR c AND d Then ...
Apakah ada argumen yang mendukung atau menentang termasuk tanda kurung asing? Apakah pengalaman praktis menunjukkan bahwa itu layak termasuk mereka untuk dibaca? Atau itu pertanda bahwa seorang pengembang perlu benar-benar duduk dan menjadi percaya diri dengan dasar-dasar bahasa mereka?
coding-style
operator-precedence
Jeff Bridgman
sumber
sumber
2 * 3 + 2
mungkin sama(2 * 3) + 2
tetapi yang kedua lebih mudah dibaca.Jawaban:
Pengembang yang baik berusaha untuk menulis kode yang jelas dan benar . Mengurung dalam kondisi, bahkan jika mereka tidak benar-benar diperlukan, membantu dengan keduanya.
Untuk kejelasan , pikirkan tanda kurung seperti komentar dalam kode: mereka tidak benar-benar diperlukan, dan secara teori pengembang yang kompeten harus dapat mengetahui kode tanpa mereka. Namun, isyarat ini sangat membantu, karena:
Selain itu, tanda kurung tambahan, seperti lekukan, spasi putih, dan standar gaya lainnya, membantu mengatur kode secara visual dengan cara yang logis.
Adapun kebenaran , kondisi tanpa tanda kurung adalah resep untuk kesalahan konyol. Ketika mereka terjadi, mereka bisa menjadi bug yang sulit ditemukan - karena seringkali kondisi yang salah akan berlaku dengan benar sebagian besar waktu, dan hanya kadang-kadang gagal.
Dan bahkan jika Anda melakukannya dengan benar, orang berikutnya yang mengerjakan kode Anda mungkin tidak, baik menambahkan kesalahan pada ekspresi atau salah memahami logika Anda dan dengan demikian menambahkan kesalahan di tempat lain (seperti yang ditunjukkan LarsH dengan benar).
Saya selalu menggunakan tanda kurung untuk ekspresi yang menggabungkan
and
danor
(dan juga untuk operasi aritmatika dengan masalah prioritas yang serupa).sumber
Itu kurang penting apakah Anda yakin dengan pemahaman bahasa Anda. Yang lebih penting adalah pemahaman bahasa n00b yang mengikuti Anda.
Tulis kode Anda dengan cara yang paling jelas mungkin. Tanda kurung ekstra sering (tetapi tidak selalu) membantu. Menempatkan hanya satu pernyataan pada satu baris sering membantu. Konsistensi dalam gaya pengkodean sering membantu.
Ada yang namanya kurung terlalu banyak, tetapi itu adalah salah satu situasi di mana Anda tidak akan memerlukan nasihat - Anda akan mengetahuinya ketika Anda melihatnya. Pada titik refactor kode Anda untuk mengurangi kompleksitas pernyataan daripada menghapus tanda kurung.
sumber
There is such a thing as too many parenthesis
- Anda jelas bukan lisper;)Iya
Anda harus selalu menggunakan tanda kurung ... Anda tidak mengontrol urutan prioritas ... pengembang kompilator tidak. Ini adalah kisah yang terjadi pada saya tentang tidak menggunakan tanda kurung. Ini mempengaruhi ratusan orang selama periode dua minggu.
Alasan Dunia Nyata
Saya mewarisi aplikasi bingkai utama. Suatu hari, tiba-tiba ia berhenti bekerja. Itu saja ... puf itu baru saja berhenti.
Pekerjaan saya adalah membuatnya bekerja secepat mungkin. Kode sumber belum dimodifikasi selama dua tahun, tetapi tiba-tiba saja berhenti. Saya mencoba untuk mengkompilasi kode dan itu rusak pada baris XX. Saya melihat garis XX dan saya tidak tahu apa yang membuat garis XX putus. Saya meminta spesifikasi terperinci untuk aplikasi ini dan tidak ada. Jalur XX bukan pelakunya.
Saya mencetak kode dan mulai memeriksanya dari atas ke bawah. Saya mulai membuat diagram alur dari apa yang sedang terjadi. Kode itu sangat berbelit-belit sampai saya bahkan tidak bisa memahaminya. Saya menyerah mencoba untuk flowchart itu. Saya takut untuk membuat perubahan tanpa mengetahui bagaimana perubahan itu akan mempengaruhi sisa proses, terutama karena saya tidak punya rincian tentang apa yang dilakukan aplikasi atau di mana itu berada dalam rantai ketergantungan.
Jadi, saya memutuskan untuk mulai di bagian atas kode sumber dan menambahkan whitespce dan rem baris untuk membuat kode lebih mudah dibaca. Saya perhatikan, dalam beberapa kasus, ada jika kondisi yang digabungkan
AND
danOR
dan itu tidak jelas dibedakan antara data apa yang sedangAND
diedit dan data apa yang sedangOR
diedit. Jadi saya mulai meletakkan tanda kurung di sekitarAND
danOR
kondisi untuk membuatnya lebih mudah dibaca.Saat saya perlahan-lahan membersihkannya, saya secara berkala akan menyelamatkan pekerjaan saya. Pada satu titik saya mencoba mengkompilasi kode dan hal aneh terjadi. Kesalahan telah melompat melewati baris kode asli dan sekarang lebih jauh ke bawah. Jadi saya melanjutkan, melapangkan
AND
danOR
mengkondisikan orangtua . Ketika saya selesai membersihkannya, itu berhasil. Go Figure.Saya kemudian memutuskan untuk mengunjungi toko operasi dan bertanya apakah mereka baru saja memasang komponen baru pada kerangka-utama. Mereka berkata ya, kami baru saja meningkatkan kompiler. Hmmmm.
Ternyata kompiler lama mengevaluasi ekspresi dari kiri ke kanan. Versi baru dari kompiler juga mengevaluasi ekspresi dari kiri ke kanan tetapi kode ambigu, yang berarti kombinasi tidak jelas
AND
danOR
tidak dapat diselesaikan.Pelajaran yang saya pelajari dari ini ... SELALU, SELALU, SELALU menggunakan paren untuk
AND
kondisi dan kondisi yang terpisahOR
ketika mereka digunakan bersama satu sama lain.Contoh Sederhana
IF Product = 191 OR Product = 193 AND Model = "ABC" OR Product = 201 OR Product = 202 AND Model = "DEF" ...
(kode berserakan dengan beberapa di antaranya)Ini adalah versi sederhana dari apa yang saya temui. Ada kondisi lain dengan pernyataan logika gabungan boolean juga.
Saya ingat pernah membawanya ke:
IF ((Product = 191 OR Product = 193) AND Model = "ABC") OR ((Product = 201 OR Product = 202) AND Model = "DEF") ...
Saya tidak bisa menulis ulang karena tidak ada spesifikasi. Penulis asli sudah lama hilang. Saya ingat tekanan kuat. Seluruh kapal kargo terdampar di pelabuhan dan tidak dapat dimuat karena program kecil ini tidak berfungsi. Tanpa peringatan. Tidak ada perubahan pada kode sumber. Saya baru sadar untuk menanyakan Operasi Jaringan jika mereka memodifikasi apa pun setelah saya perhatikan bahwa menambahkan parens menggeser kesalahan.
sumber
Ya, jika ada campuran 'dan' dan 'atau'.
Juga ide yang bagus untuk () apa yang secara logis satu cek.
Meskipun yang terbaik adalah dengan menggunakan fungsi predikat yang telah disebut dan mengusir sebagian besar pemeriksaan dan kondisi di sana, meninggalkan jika sederhana dan dapat dibaca.
sumber
a AND b
mungkin harus diganti dengan fungsi atau nilai boolen yang dihitung sebelumnya yang memiliki nama yang lebih deskriptif.Tanda kurung secara semantis redundan, jadi kompilernya tidak peduli, tapi itu herring merah - perhatian sebenarnya adalah keterbacaan dan pemahaman programmer.
Saya akan mengambil posisi radikal di sini dan memberikan tanda "tidak" pada tanda kurung
a AND b OR c AND d
. Setiap pemrogram harus mengingat dengan hati-hati bahwa prioritas dalam ekspresi Boolean TIDAK> DAN> ATAU , seperti halnya mengingat Harap Maafkan Bibi Sally yang Terhormat untuk ekspresi aljabar. Tanda baca yang berlebihan hanya menambah kekacauan visual sebagian besar waktu dalam kode tanpa manfaat dalam keterbacaan programmer.Juga, jika Anda selalu menggunakan tanda kurung dalam ekspresi logis dan aljabar, maka Anda melepaskan kemampuan untuk menggunakannya sebagai penanda untuk "sesuatu yang rumit sedang terjadi di sini - lihatlah!" Yaitu, dalam kasus di mana Anda ingin menimpa prioritas awal dan memiliki tambahan yang dievaluasi sebelum perkalian, atau ATAU sebelum DAN, tanda kurung adalah bendera merah yang bagus untuk programmer berikutnya. Terlalu banyak menggunakan mereka ketika mereka tidak dibutuhkan, dan Anda menjadi Boy Who Cried Wolf.
Saya akan membuat pengecualian untuk apa pun di luar bidang aljabar (Boolean atau tidak), seperti ekspresi pointer di C, di mana sesuatu yang lebih rumit daripada idiom standar seperti
*p++
ataup = p->next
mungkin harus dipasangkan untuk menjaga dereferencing dan aritmatika tetap lurus. Dan, tentu saja tidak ada yang berlaku untuk bahasa seperti Lisp, Forth, atau Smalltalk yang menggunakan beberapa bentuk notasi Polandia untuk ekspresi; tetapi untuk sebagian besar bahasa umum, prioritas logis dan aritmatika sepenuhnya standar.sumber
AND
vsOR
adalah kasus yang cukup mendasar yang saya ingin tahu devs lain di tim saya tahu. Saya khawatir bahwa kadang-kadang "menggunakan tanda kurung untuk kejelasan" benar-benar "menggunakan tanda kurung jadi saya tidak perlu repot-repot untuk mempelajari prioritasnya"..member
sebelum operator unary, unary sebelum operator biner,*
dan/
sebelum+
dan-
sebelum<
dan>
dan==
sebelum&&
sebelum||
sebelum tugas. Aturan-aturan yang mudah diingat karena mereka cocok "akal sehat" saya tentang bagaimana operator biasanya digunakan (misalnya, Anda tidak akan memberikan==
diutamakan lebih besar dari+
atau1 + 1 == 2
berhenti bekerja), dan mereka menutupi 95% dari pertanyaan didahulukan aku harus .Seperti yang saya lihat:
YA Pro:
YA Kontra:
TIDAK ADA Pro:
TIDAK ADA Kekurangan:
sumber
3 * a^2 + 2 * b^2
lebih mudah dibaca daripada(3 * (a^2)) + (2 * (b^2))
, karena format dan prioritasnya sudah biasa dan standar. Demikian juga, Anda bisa (menjadi ekstrem) melarang penggunaan fungsi dan makro (atau kompiler!) Untuk membuat semantik kode Anda lebih eksplisit. Jelas saya tidak menganjurkan itu, tetapi saya berharap untuk menjawab pertanyaan Anda tentang mengapa harus ada batasan (keseimbangan) dalam membuat semuanya eksplisit.Jika tidak ada orang lain yang harus melihat kode saya lagi, saya tidak berpikir saya akan peduli.
Tapi, dari pengalaman saya:
Saya hampir selalu melakukan ini karena saya percaya pada kemampuan saya untuk dengan cepat membaca dan tidak membuat kesalahan kecil lebih banyak dengan orangtua daripada tidak ada yang lain.
Dalam kasus Anda, saya hampir pasti akan melakukan sesuatu seperti:
Ya, lebih banyak kode. Ya, saya bisa melakukan operator bool mewah sebagai gantinya. Tidak, saya tidak suka kesempatan ketika membaca kode 1+ tahun di masa depan saya salah membaca operator bool mewah. Bagaimana jika saya menulis kode dalam bahasa yang memiliki prioritas AND / OR yang berbeda dan harus melompat kembali untuk memperbaikinya? Apakah saya akan pergi, "aha! Saya ingat hal kecil yang pintar ini yang saya lakukan! Saya tidak harus memasukkan parens ketika saya menulis ini tahun lalu, hal yang baik saya ingat sekarang!" jika itu terjadi (atau lebih buruk, orang lain yang tidak menyadari kepintaran ini atau dilemparkan ke dalam situasi tipe "fix secepat")?
Memisahkan dengan () membuatnya jauh lebih mudah untuk dengan cepat menelusuri dan memahami nanti ...
sumber
ab = a AND b
?ab
akan tetap tidak berubah jika tidaka AND b
.Kasus umum
Dalam C #, perkalian dan pembagian memiliki prioritas di atas penambahan dan pengurangan.
Namun, StyleCop, alat yang menerapkan gaya umum di seluruh basis kode dengan tujuan tambahan untuk mengurangi risiko bug yang disebabkan oleh kode yang mungkin tidak cukup jelas, memiliki aturan SA1407 . Aturan ini akan menghasilkan peringatan dengan sepotong kode seperti ini:
Jelas bahwa hasilnya adalah
7
dan tidak9
, tetapi tetap saja, StyleCop menyarankan untuk menempatkan tanda kurung:Kasus khusus Anda
Dalam kasus khusus Anda, ada prioritas AND dibandingkan dengan OR dalam bahasa tertentu yang Anda gunakan.
Ini bukan bagaimana setiap bahasa berperilaku. Banyak orang lain memperlakukan AND dan OR secara setara.
Sebagai pengembang yang sebagian besar bekerja dengan C #, ketika saya melihat pertanyaan Anda pertama kali dan membaca potongan kode tanpa membaca apa yang telah Anda tulis sebelumnya, godaan pertama saya adalah berkomentar bahwa kedua ungkapan itu tidak sama. Semoga, saya sudah membaca seluruh pertanyaan sebelum berkomentar.
Kekhasan ini dan risiko yang mungkin diyakini sebagian pengembang bahwa AND dan OR memiliki prioritas yang sama membuatnya lebih penting untuk menambahkan tanda kurung.
Jangan menulis kode dengan tujuan untuk menunjukkan bahwa Anda cerdas. Tulis kode dengan tujuan keterbacaan, termasuk oleh orang-orang yang mungkin tidak terbiasa dengan setiap aspek bahasa.
sumber
Seperti yang dikatakan semua orang, gunakan tanda kurung setiap kali membuat ekspresi lebih mudah dibaca. Namun jika ekspresi rumit saya sarankan untuk memperkenalkan fungsi baru untuk subekspresi .
sumber
Jika Anda benar-benar menggunakan bahasa dalam bentuk tunggal, mungkin. Sekarang ambil semua bahasa yang Anda tahu, dari usia tua hingga yang paling modern, dari dikompilasi untuk scripting ke SQL ke DSL Anda sendiri yang Anda ciptakan bulan lalu.
Apakah Anda ingat aturan prioritas yang tepat untuk masing-masing bahasa ini, tanpa melihat?
sumber
"Haruskah saya menggunakan tanda kurung dalam pernyataan logis meskipun tidak diperlukan."
Ya, karena dua orang akan merasa terbantu:
Programmer berikutnya, yang memiliki pengetahuan, kompetensi atau gaya mungkin berbeda
Masa depan Anda yang kembali ke kode ini di kemudian hari!
sumber
Kondisional yang kompleks adalah "aljabar boolean", yang Anda tulis dalam beberapa cara yang, yah, membuatnya tampak persis seperti aljabar, dan Anda pasti akan menggunakan parens untuk aljabar , bukan?
Aturan yang sangat berguna adalah negasi:
Atau, dalam format yang sedikit lebih jelas:
yang benar - benar jelas hanya aljabar ketika dituliskan sebagai:
Tetapi kita juga bisa menerapkan pemikiran untuk penyederhanaan dan perluasan aljabar:
walaupun dalam kode Anda harus menulis:
atau, dalam format yang sedikit lebih jelas:
Pada dasarnya, kondisi masih hanya ekspresi aljabar, dan dengan jelas menggunakan tanda kurung, Anda dapat lebih mudah menerapkan berbagai aturan aljabar yang sudah Anda ketahui untuk ekspresi, termasuk konsep "menyederhanakan atau memperluas rumus ini".
sumber
!(A + B) <=> !A + !B
dan-1*(A + B) = -A + -B
seharusnya tidak operator telah membalik dari+
ke*
dalam ekspresi kedua?Saya akan menggunakan tanda kurung bahkan jika itu opsional, mengapa karena membantu untuk lebih memahami bagi semua orang, untuk orang yang menulis kode serta yang siap untuk melihat kode itu. Dalam kasus Anda, bahkan para operator boolean telah mendahului itu mungkin berhasil pada awalnya, tetapi kami tidak dapat mengatakan itu akan membantu Anda dalam setiap kasus. jadi saya lebih suka tanda kurung pengguna dalam kondisi apa pun yang mungkin memerlukannya atau opsional.
sumber
Iya. Anda harus menggunakan dalam hal apa pun ketika Anda merasa kode Anda akan lebih jelas. Ingat kode Anda harus cukup jelas sehingga orang lain dapat mengerti tanpa membaca komentar Anda di dalam kode. Jadi itu adalah praktik yang baik untuk menggunakan kurung dan kawat gigi. Juga perlu diingat bahwa itu mungkin tergantung pada praktik khusus perusahaan / tim Anda. Hanya pertahankan satu pendekatan dan jangan campur.
sumber