Mengapa pengembang C # membuka kurung baris baru? [Tutup]

44

Saya telah menghabiskan sebagian besar beberapa tahun terakhir bekerja terutama dengan C # dan SQL. Setiap programmer yang pernah bekerja sama dengan saya pada waktu itu memiliki kebiasaan untuk menempatkan kurung buka fungsi atau pernyataan aliran kontrol pada baris baru. Jadi ...

public void MyFunction(string myArgument)
{
     //do stuff
}

if(myBoolean == true)
{
    //do something
}
else
{
    //do something else
}

Saya selalu dikejutkan oleh betapa borosnya ruang ini, terutama dalam pernyataan if / else. Dan saya tahu ada alternatif di versi C # kemudian, seperti:

if(myBoolean == true)
    //do something on one line of code

Tapi hampir tidak ada yang menggunakannya. Semua orang melakukan hal yang keriting-menguatkan pada baris baru.

Kemudian saya kembali melakukan JavaScript setelah lama absen. Dalam ingatan saya, pengembang JavaScript dulu melakukan hal yang sama keriting-kurawal-baris baru tetapi dengan semua perpustakaan dan hal-hal baru yang mewah, sebagian besar pengembang menempatkan penjepit pembukaan setelah deklarasi:

function MyJavaScriptFunction() {
    //do something
}

Anda dapat melihat artinya dalam hal ini, karena sejak menggunakan closure dan fungsi pointer telah menjadi populer di JavaScript, ini menghemat banyak ruang dan membuat semuanya lebih mudah dibaca. Jadi saya bertanya-tanya mengapa itu tidak dilihat sebagai hal yang dilakukan dalam C #. Bahkan, jika Anda mencoba konstruksi di atas dalam Visual Studio 2013, itu sebenarnya memformat ulang untuk Anda, menempatkan brace pembuka di baris baru!

Sekarang, saya baru saja melihat pertanyaan ini pada Code Review SE: https://codereview.stackexchange.com/questions/48035/questions-responses-let-me-tell-you-about-you Di mana saya mengetahui bahwa di Jawa, a bahasa Saya tidak terlalu terbiasa dengan itu, itu dianggap de-rigor untuk membuka kurung kurawal Anda tepat setelah deklarasi, dalam mode JavaScript modern.

Saya selalu mengerti bahwa C # awalnya dimodelkan setelah Java, dan terus ke banyak standar pengkodean basal yang sama. Tetapi dalam contoh ini, sepertinya tidak. Jadi saya kira pasti ada alasan yang bagus: apa alasannya? Mengapa pengembang C # (dan Visual Studio) memberlakukan kurung keriting pada baris baru?

Bob Tway
sumber
30
Konvensi hanyalah itu.
Oded
19
Visual Studio tidak memberlakukan apa pun, gaya kode dapat dikonfigurasi. Sesuatu harus menjadi default. Default mana yang "lebih baik" adalah bikeshedding dengan urutan tertinggi.
Phoshi
23
Penjepit di ujung garis adalah standar K&R C kuno. Kernighan dan Ritchie menemukan bahasa C ketika tampilan komputer hanya memiliki 25 baris (23 jika Anda menambahkan judul dan baris status). Bukan itu masalahnya lagi, kan? Yang penting adalah konsistensi di seluruh proyek. Ada yang juga studi ilmiah yang menunjukkan bahwa penjepit pada baris sendiri (menjorok ke tingkat yang sama seperti kode, sebenarnya) meningkatkan kode pemahaman meskipun apa yang orang berpikir mereka berpikir tentang estetika.
Craig
10
C # selalu mendukung mengevaluasi satu baris kode setelah kondisional, omong-omong. Bahkan, itulah satu - satunya yang dilakukannya, bahkan sekarang. Menempatkan kode dalam kurung setelah ekspresi bercabang hanya membuat instruksi itu menjadi goto (kompiler membuat ruang lingkup menggunakan instruksi jmp). C ++, Java, C # dan JavaScript semuanya lebih atau kurang didasarkan pada C, dengan aturan penguraian yang mendasari yang sama, untuk sebagian besar. Jadi dalam pengertian itu, C # tidak "berdasarkan Java."
Craig
10
Sebagai catatan, if(myBoolean == true)tidak masuk akal bagi saya. Sementara kita melakukannya, sementara tidak if ((myBoolean == true) == true)?? Adil if (myBoolean)dan itu sudah cukup. Maaf, kencing kesayangan saya.
Konrad Morawski

Jawaban:

67

Penjepit pada akhir baris adalah standar K&R C kuno, dari buku Brian Kernighan dan Dennis Ritchie, The C Programming Language , yang mereka terbitkan pada 1978 setelah ikut menciptakan sistem operasi UNIX dan bahasa pemrograman C (saya pikir C adalah sebagian besar dirancang oleh Ritchie), di AT&T.

Dulu ada perang api tentang "gaya penjepit yang benar."

Ritchie menemukan bahasa C, dan Kernighan menulis tutorial pertama, ketika tampilan komputer hanya menunjukkan beberapa baris teks. Bahkan, pengembangan UNICS (kemudian UNIX) dimulai pada DEC PDP-7, yang menggunakan mesin tik, printer, dan pita kertas untuk antarmuka pengguna. UNIX dan C selesai pada PDP-11, dengan terminal teks 24-baris. Jadi ruang vertikal memang sangat mahal. Kita semua memiliki tampilan yang sedikit lebih baik dan printer resolusi lebih tinggi hari ini, kan? Maksud saya, saya tidak tahu tentang Anda, tetapi saya memiliki tiga (3) tampilan 1080p 24 "di depan saya sekarang. :-)

Juga, begitu banyak dari buku kecil itu Bahasa Pemrograman C adalah contoh kode yang menempatkan kawat gigi pada ujung garis bukannya pada garis mereka sendiri yang diduga menghemat jumlah uang yang cukup besar pada pencetakan.

Yang benar-benar penting adalah konsistensi di seluruh proyek, atau setidaknya dalam file kode sumber yang diberikan.

Ada yang juga studi ilmiah yang menunjukkan bahwa penjepit pada baris sendiri (menjorok ke tingkat yang sama seperti kode, sebenarnya) meningkatkan kode pemahaman meskipun apa yang orang berpikir mereka berpikir tentang estetika. Itu membuatnya sangat jelas bagi pembaca, secara visual dan naluriah, kode mana yang berjalan dalam konteks mana.

if( true )
    {
    // do some stuff
    }

C # selalu mendukung mengevaluasi satu perintah setelah ekspresi bercabang, omong-omong. Bahkan, itulah satu-satunya yang dilakukannya, bahkan sekarang. Menempatkan kode dalam kurung setelah ekspresi bercabang hanya membuat satu perintah menjadi goto (kompiler membuat ruang lingkup menggunakan instruksi jmp). C ++, Java, C # dan JavaScript semuanya lebih atau kurang didasarkan pada C, dengan aturan penguraian yang mendasari yang sama, untuk sebagian besar. Jadi dalam pengertian itu, C # tidak "berdasarkan Java."

Menyimpulkan, ini adalah sedikit dari isu agama / api perang. Tapi ada yang studi sehingga cukup jelas bahwa mengatur kode dalam blok meningkatkan manusia pemahaman. Kompiler tidak peduli. Tapi ini juga terkait dengan alasan mengapa saya tidak pernah meletakkan baris kode setelah cabang tanpa kawat gigi - itu terlalu mudah bagi saya atau programmer lain untuk menampar baris kode lain di sana nanti dan tergelincir pada kenyataan bahwa itu tidak akan jalankan dalam konteks yang sama dengan baris tepat sebelum atau sesudahnya.

EDIT : Coba lihat bug Applegoto fail untuk contoh sempurna dari masalah yang tepat ini, yang memiliki konsekuensi dunia nyata yang sangat serius.

if( true )
    doSomething();

menjadi...

if( true )
    doSomething();
    doSomethingElse();

Dalam hal ini, doSomethingElse()dieksekusi setiap saat, terlepas dari hasil tes, tetapi karena indentasi ke tingkat yang sama dengan doSomething()pernyataan, mudah untuk dilewatkan. Ini tidak bisa dibantah; mempelajari kembali hal ini. Ini adalah sumber besar bug yang dimasukkan ke dalam kode sumber selama pemeliharaan.

Namun, saya akui bahwa sintaksis penutupan JavaScript terlihat agak konyol dengan kawat gigi pada baris mereka sendiri ... secara estetika. :-)

Craig
sumber
13
Bagian tentang blok dalam kondisi sedikit menyesatkan. Dalam C, kondisional selalu memiliki pernyataan tunggal, tetapi blok (alias pernyataan majemuk) adalah sejenis pernyataan . C # mengikuti preseden ini. Bagaimanapun, evaluasi kondisional selalu menyiratkan semacam kondisional goto atau instruksi percabangan, karena sifat linier dari semua set instruksi umum. Kondisional tanpa blok tidak berbeda secara kualitatif dari kondisional dengan blok (kecuali berkaitan dengan pelingkupan).
amon
3
@Craig, ingat, ini di Bell Labs, saat Bell Labs disewa untuk "melakukan hal-hal yang menarik" yang tidak harus diharuskan praktis untuk apa pun. Tempatkan orang-orang pintar di gedung, minta mereka melakukan riset yang menarik, pindahkan mereka dari apa yang mereka lakukan tidak "menarik", dan, yang lucu, hal-hal MENARIK (seperti transistor dan Unix) cenderung muncul. DARPA memiliki semacam fokus yang sama, pada awalnya, dan mereka mendanai BANYAK pekerjaan yang baik, atas nama penelitian dasar.
John R. Strohm
3
@Craig: Di masa Pascal / Delphi yang lama, saya biasanya menghindarinya untuk blok baris tunggal, karena Pascal menggunakan begindan endsebagai pengganti kawat gigi, yang membuat kesalahan seperti itu sangat sulit untuk dilewatkan, dan itu juga lebih ketat mengenai penempatan titik koma - tetapi setelah menghabiskan 4 hari tahun lalu men-debug masalah dalam embedded C yang akhirnya disebabkan oleh kurangnya penempatan brace seseorang ..... Saya pikir harus ada opsi kompiler yang membuat kawat gigi wajib untuk pernyataan kontrol!
Mark K Cowan
12
Berikan referensi untuk "... studi ilmiah yang menunjukkan bahwa penjepit pada jalurnya sendiri ...". Tanpa setidaknya dua referensi (kalau tidak itu akan belajar , bukan belajar ), itu hanya menembak secara acak ke udara.
ErikE
2
@Craig, dapatkah Anda memberikan beberapa petunjuk bagaimana menemukan studi penelitian yang Anda sebutkan itu?
Grzegorz Adam Kowalski
30

Alasan pengembang C # melakukannya adalah karena itu adalah pengaturan default dari auto-formatter Visual Studio. Meskipun pengaturan ini dapat diubah, kebanyakan orang tidak, dan dengan demikian semua pengembang dalam tim harus mengikuti mayoritas.

Adapun mengapa ini adalah default di Visual Studio, saya tidak tahu.

Timwi
sumber
15
Ini adalah default di Visual Studio karena itu adalah gaya pengkodean yang diterima secara umum di Microsoft, jauh ke belakang, dan bahkan pada setidaknya beberapa tim di Microsoft, gaya itu bukan hanya kawat gigi pada jalurnya sendiri, tetapi kawat gigi pada jalurnya sendiri dan menjorok. Jadi itu adalah opsi di Visual Studio, juga (saya pribadi lebih suka).
Craig
20
@Craig: Ewwwwwwwww
Lightness Races dengan Monica
5
@PreferensiBean Hmm. Secara pribadi saya tidak suka gaya K&R, karena tanda kurung hanya hilang dalam kebisingan di ujung garis dan teks terlihat kasar bagi saya, yang bukan hanya preferensi estetika, tetapi memiliki dampak aktual pada keterbacaan / pemahaman. Saya suka spasi vertikal. Itu sedikit berbeda pada monitor 12 "dengan 24 baris teks di masa lalu ketika ruang vertikal berharga.
Craig
10
@Craig: Itu bukan alasan untuk membuat kurung kurawal: P
Lightness Races dengan Monica
2
@Craig Membuat karyawan Microsoft sengsara?
Mateen Ulhaq
18

Seperti yang saya hipotesiskan dalam jawaban ini di sini - https://softwareengineering.stackexchange.com/a/159081/29029 - Saya kira keputusan untuk pergi dengan penguat Allman bisa menjadi tanda warisan Pascal, mengingat Hejlsberg menciptakan Delphi sebelum ia merancang C # . Sama seperti kasus Pascal untuk nama metode.

Secara pribadi saya percaya dalam mengikuti pepatah "di Roma lakukan seperti yang dilakukan orang Roma". Saya menggunakan Allman di C #, tetapi K&R di Jawa. Saya sangat terbiasa dengan itu bahwa beralih ke konvensi baik cara itu menggelisahkan bagi saya.

Saya percaya bahwa beberapa keragaman konvensi sebenarnya bermanfaat bagi pengembang "multibahasa" karena membantu mengingat bahasa yang sedang mereka koding saat ini dan membuatnya mudah untuk membedakan berbagai kebiasaan. Secara mental, ini setara dengan memori otot.

Konrad Morawski
sumber
7
+1 untuk baris "pengembang multi bahasa", sebenarnya. Saya lebih suka kawat gigi pada baris mereka sendiri dan lekukan. Namun, dalam mengerjakan, misalnya, proyek ASP.NET (MVC), saya menemukan bahwa saya suka C # dengan gaya "benar", dan JavaScript dengan gaya "JavaScript". Itu sedikit menjengkelkan, tetapi jujur ​​bagian dari itu adalah bahwa sintaks penutupan JavaScript lebih menarik dengan penjepit di akhir baris. Jadi saya juga budak estetika seperti orang lain ...
Craig
PascalCase untuk nama metode adalah standar di Microsoft lama sebelum Anders Hejlsberg meninggalkan Borland untuk menjadi insinyur perangkat lunak terkemuka di Microsoft.
Craig
2
Menariknya, saya menggunakan Allman untuk semua bahasa penyangga blok. Namun, saya menjadi semakin tertarik pada bagaimana konversi indentasi pra-pemrosesan menjadi blok keriting mungkin terlihat di Jawa. Kode "java" mungkin terlihat sangat bersih, begitu saya membungkus pikiran pengenalan pola saya di sekitarnya. Saya pikir Python mungkin benar-benar melakukannya dengan benar: Benar-benar tidak ada alasan bagus untuk kawat gigi dalam bahasa.
tgm1024
Menggunakan spasi putih untuk mengontrol aliran program adalah kegilaan. Python populer akhir-akhir ini, tetapi aspek Python ini sudah sedikit gila sejak pertama kali muncul.
Craig
@Craig penggemar Python di sini, mencoba menyelesaikan sesuatu dalam javascript. Melihat jawaban Anda yang lain, dan hasil edit Anda tentang goto fail, menggunakan indentasi untuk mengontrol aliran program adalah apa yang manusia ingin lakukan, jadi apa yang Anda lihat adalah apa yang dijalankan. Jika itu salah indent itu jelas tidak bekerja. Harus memecahkan kode apa yang dimaksud kawat gigi, apakah mereka benar-benar mencerminkan lekukan, adalah pekerjaan tambahan di atas pemahaman program. Lekukan berlebihan untuk kawat gigi, jadi mengapa programmer menggunakannya jika kawat gigi berguna? Sarang yang dalam tidak bisa dipahami dalam bahasa apa pun. Jus 'sayin'.
Neil_UK
14

Konvensi yang Anda asosiasikan dengan Jawa adalah gaya K&R, atau "Satu gaya penyangga sejati," dan aslinya berasal dari C. Halaman indent-style dari File Jargon yang terhormat menunjukkan berapa usia perbedaannya.

Saya selalu berpikir bahwa gaya Allman dan variannya merupakan cerminan dari bagaimana penulis berpikir tentang kode, meningkatkan pembatas blok ke tingkat kata kunci yang mirip dengan bagaimana beberapa bahasa menggunakan "mulai" dan "berakhir" di sekitar blok kode.

John Bickers
sumber
Saya mendapat kesan bahwa hari ini OTBS (satu gaya penyangga sejati) juga menyiratkan tidak pernah meninggalkan kawat gigi setelah pernyataan kontrol, bahkan untuk satu baris kode. Lihat bug kegagalan Apple goto.
Craig