Mengapa sebagian besar bahasa pemrograman tidak memblokir komentar?

18

Beberapa melakukannya, tetapi tidak ada yang populer sejauh yang saya tahu. Apakah ada hal buruk tentang komentar bersarang?

Saya berencana memblokir komentar di bahasa (kecil) yang saya kerjakan, tapi saya ingin tahu apakah ini ide yang buruk.

amara
sumber
kembali beberapa jawaban: ohh, itu masuk akal =) saya benar-benar melakukan komentar blok bersarang itu; walaupun saya memiliki tahap lexing terpisah, itu bukan jenis yang membatasi SK-logika yang dijelaskan.
@ Vuntic: Jika Anda memiliki tahap lexing terpisah yang menggunakan hal-hal yang lebih rumit daripada ekspresi reguler, Anda mungkin memiliki masalah kinerja. RE cepat dan mudah digunakan dengan menerapkan DFA.
David Thornley
Ini menangkap lebih banyak kesalahan lebih awal untuk tidak mengizinkan bersarang
4
@ David: ... tidak sama sekali. Ini sebenarnya sangat cepat.
amara
Saya menyarankan bahwa jika Anda ingin memperbolehkan komentar bersarang, Anda mengizinkan tag komentar awal ditandai dengan token, dan mensyaratkan bahwa jika tag komentar awal ditandai, tag komentar akhir harus ditandai secara identik. Itu akan memungkinkan tag awal / akhir tidak seimbang dengan cepat diidentifikasi, dan menghindari kemungkinan bug yang disebabkan oleh tag tidak seimbang yang tidak terdeteksi.
supercat

Jawaban:

6

Satu hal yang belum ada yang disebutkan, jadi saya akan menyebutkannya: Keinginan untuk membuat komentar sering menunjukkan bahwa programmer melakukan Doing It Wrong.

Pertama, mari kita sepakat bahwa satu-satunya waktu "bersarang" atau "tidak bersarang" terlihat oleh programmer adalah ketika programmer menulis sesuatu secara struktural seperti ini:

do_something();
/* comment /* nested comment */ more comment */
do_something_else();

Sekarang, kapan hal seperti itu muncul dalam praktik? Tentu saja programmer tidak akan menulis komentar bersarang yang benar - benar terlihat seperti cuplikan di atas! Tidak, dalam praktiknya ketika kita membuat komentar sarang (atau berharap kita bisa membuat sarang), itu karena kita ingin menulis sesuatu seperti ini:

do_something();  /* do a thing */
/* [ajo] 2017-12-03 this turned out to be unnecessary
do_something_else(); /* do another thing */
*/

Dan ini BURUK. Ini bukan pola yang kami (sebagai perancang bahasa) ingin dorong! Cara yang benar untuk menulis cuplikan di atas adalah:

do_something();  /* do a thing */

Kode "salah" itu, awal yang salah atau apa pun itu, tidak termasuk dalam basis kode. Miliknya, paling tidak, dalam sejarah kontrol sumber. Idealnya, Anda bahkan tidak akan pernah menulis kode yang salah, bukan? Dan jika kode yang salah melayani tujuan di sana, dengan memperingatkan pengelola untuk tidak mengembalikannya karena alasan tertentu, mungkin itu pekerjaan untuk komentar kode yang ditulis dengan baik dan disengaja. Mencoba untuk mengekspresikan "jangan lakukan X" dengan hanya meninggalkan beberapa kode lama yang melakukan X, tetapi berkomentar, bukanlah cara yang paling mudah dibaca atau efektif untuk mencegah orang melakukan X.

Ini semua bermuara pada aturan praktis sederhana yang mungkin pernah Anda dengar sebelumnya: Jangan berkomentar kode. (Mencari frase ini akan muncul sebuah banyak dari pendapat di perjanjian .)

Sebelum Anda bertanya: ya, bahasa seperti C, C #, dan C ++ sudah memberikan programmer lain alat untuk "komentar keluar" blok besar kode: #if 0. Tapi ini hanya aplikasi khusus dari preprocessor C, yang merupakan alat besar dan berguna dalam dirinya sendiri. Sebenarnya akan sangat sulit dan casey khusus untuk bahasa untuk mendukung kompilasi bersyarat dengan #ifnamun tidak mendukung #if 0.


Jadi, kami telah menetapkan bahwa komentar bersarang hanya relevan ketika programmer berkomentar kode; dan kami telah menetapkan (melalui konsensus dari banyak programmer berpengalaman) bahwa mengomentari kode adalah hal yang buruk.

Untuk melengkapi silogisme, kita harus menerima bahwa perancang bahasa memiliki minat dalam mempromosikan Hal-Hal Baik dan mengecilkan Hal-Hal Buruk (dengan asumsi bahwa semua yang lain adalah sama).

Dalam kasus komentar bersarang, semua yang lain adalah sama - Anda dapat dengan aman mengabaikan rendah sebagai jawaban bahwa klaim bahwa parsing bersarang /*akan entah bagaimana menjadi "sulit" untuk parser. (Bersarang /*tidak lebih sulit dari bersarang (, yang harus ditangani oleh setiap pengurai di dunia.)

Jadi, semuanya sederajat, haruskah perancang bahasa memudahkan untuk membuat sarang komentar (yaitu, untuk memberikan kode komentar), atau sulit? Ingat bahwa mengomentari kode adalah hal yang buruk.

QED


Catatan kaki. Perhatikan bahwa jika Anda tidak mengizinkan komentar bersarang, maka

hello /* foo*/bar.txt */ world

adalah "komentar" yang menyesatkan - sama dengan

hello bar.txt */ world

(yang kemungkinan merupakan kesalahan sintaksis). Tapi jika Anda melakukan mengijinkan komentar bersarang, maka

hello /* foo/*.txt */ world

adalah "komentar" yang menyesatkan - sama dengan

hello

tetapi membiarkan komentar terbuka sampai akhir file (yang lagi-lagi hampir pasti merupakan kesalahan sintaksis). Jadi tidak ada cara yang khususnya kurang rentan terhadap kesalahan sintaksis yang tidak disengaja. Satu-satunya perbedaan adalah bagaimana mereka menangani antipattern yang disengaja dari kode komentar.

Quuxplusone
sumber
1
Saya memiliki pendapat yang berbeda berdasarkan fakta - saya tidak melihat segalanya (dan Anda juga tidak). Jadi sementara aturan emas seperti "Jangan komentar kode" terlihat bagus, hidup memiliki jalannya sendiri. Dalam kasus khusus ini, saya melakukannya sangat sering sebagai saklar, ketika saya menguji beberapa fitur baru dan harus secara bertahap memperkenalkan beberapa kode, jadi saya berkomentar kode, kemudian kurang, kurang, kurang, dan akhirnya saya memiliki karya dan saya dapat menghapus semua komentar (lebih dari kode). Bahasa saya yang sempurna tentu saja akan mendukung komentar bersarang :-).
greenoldman
@greenoldman: Sebagian besar bahasa tidak memiliki komentar yang dapat di-nestable, tetapi mereka akan memiliki beberapa fitur aktual untuk "menghapus satu blok kode" yang lebih jarang digunakan daripada fitur "tinggalkan komentar". C #if DEADadalah contoh kanonik dan dirancang terbaik. Dalam banyak bahasa Anda hanya dapat membungkus kode mati dalam setara dengan if (DEAD). Dan di banyak IDE, Anda sebenarnya dapat menghapus kode mati dan mengandalkan Ctrl + Z dan / atau kontrol versi untuk mendapatkannya kembali jika Anda menginginkannya. Meninggalkan komentar, docstring, apa pun, yang teksnya adalah kode mati, masih merupakan opsi terburuk untuk dibaca.
Quuxplusone
11

Karena sebagian besar implementasi menggunakan tahapan lexing dan parsing yang terpisah, dan untuk lexing mereka menggunakan ekspresi reguler lama yang biasa. Komentar diperlakukan sebagai spasi putih - yaitu, token yang diabaikan, dan karenanya harus diselesaikan sepenuhnya dalam pass lexing. Satu-satunya keuntungan dari pendekatan ini adalah kecepatan parsing. Banyak kerugian termasuk keterbatasan parah pada sintaksis (mis., Kebutuhan untuk mempertahankan serangkaian kata kunci yang tetap dan tidak tergantung konteks).

Logika SK
sumber
3
Saya tidak setuju dengan 'sebagian besar' saat ini. Tentu saja itu cara tradisional, tetapi saya tahu bahwa untuk C, EDG menggabungkan preprocessor, lexing dan parsing, dan saya menduga bahwa baik GCC dan Microsoft juga. Manfaatnya adalah memungkinkan Anda menerapkannya secara terpisah jika perlu.
Andrew Aylett
Dentang juga melakukan hal yang sama. Tapi itu masih hanya sebagian kecil dari kompiler bahasa populer yang ada.
SK-logic
@Neil Butterworth, lihatlah mcs, javac, gcc (ya, itu menambal kembali lexer, tetapi masih merupakan lexing pass khusus), dentang (sama dengan gcc), dmd, fpc, dan banyak lagi.
SK-logic
Tidak ada yang menggunakan ekspresi reguler dalam lexing mereka untuk kompiler non-sepele.
Nuoji
@ Nuoji - untuk yang non-sepele - pasti. Tetapi mereka yang bergantung pada alat fleksibel dan sejenisnya melakukannya.
SK-logic
7

Sangat mungkin untuk membuat lexer yang dapat menangani komentar bersarang. Saat memakan ruang putih, saat dilihat /*dapat menambah penghitung kedalaman, dan mengurangi saat melihatnya */, dan berhenti saat kedalamannya nol. Yang mengatakan, saya telah melakukan banyak parser, dan tidak pernah menemukan alasan yang bagus untuk komentar ke sarang.

Jika komentar dapat bersarang, maka downside adalah mudah untuk mendapatkan ujungnya tidak seimbang, dan kecuali Anda memiliki editor mewah, itu bisa menyembunyikan kode yang Anda anggap ada.

Sisi positif dari komentar yang tidak bersarang adalah sesuatu seperti ini:

/*
some code
more code
blah blah blah
/**/

di mana Anda dapat dengan mudah mengomentari kode masuk atau keluar dengan menghapus atau menambahkan baris pertama - edit 1-baris. Tentu saja, jika kode itu sendiri berisi komentar, ini akan rusak, kecuali jika Anda juga mengizinkan //komentar gaya C ++ di sana. Jadi itulah yang cenderung saya lakukan.

Mike Dunlavey
sumber
1
//komentar juga bergaya C99.
JAB
Atau, bahasa dapat menentukan awal-komentar /*$token, di mana identifierada token alfanumerik, dan akhir komentar adalah token$*/. Akan relatif mudah bagi tokenizer untuk memasukkan kode untuk memverifikasi bahwa setiap tanda akhir komentar berisi token yang sesuai untuk blok komentar awal yang cocok.
supercat
5

Karena tidak ada orang lain yang menyebutkannya, saya akan mendaftar beberapa bahasa yang mendukung komentar bersarang: Rexx, Modula-2, Modula-3, Oberon. Terlepas dari semua keluhan di sini tentang masalah kesulitan dan kecepatan, tidak satu pun dari mereka yang tampaknya memiliki masalah besar.

Rugxulo
sumber
4
Yang saya tambahkan: Haskell, Frege
Ingo
Didukung oleh Scala juga.
Matt R
4

Hal yang baik dari komentar blok bersarang adalah Anda dapat mengomentari sebagian besar kode dengan mudah (well, hampir, kecuali Anda memiliki urutan akhir komentar blok dalam konstanta string).

Metode alternatif adalah dengan menambahkan beberapa baris dengan urutan mulai komentar baris jika Anda memiliki editor yang mendukungnya.

Haskell memiliki komentar blokir, tetapi kebanyakan orang tampaknya tidak memperhatikan atau mengeluh tentang hal itu. Saya kira ini karena orang yang tidak mengharapkan komentar bersarang cenderung menghindarinya karena ini akan menjadi kesalahan leksikal dalam bahasa lain.

Ingo
sumber
3

Mendukung komentar blok bersarang memperumit parser, yang merupakan pekerjaan yang lebih banyak dan dapat meningkatkan waktu kompilasi. Saya kira itu bukan fitur yang sangat dibutuhkan untuk sebuah bahasa, jadi lebih baik menggunakan waktu dan upaya untuk peningkatan dan optimalisasi lainnya.

Menurut saya, kesederhanaan selalu merupakan hal yang baik dalam mendesain apa pun. Ingatlah bahwa lebih mudah untuk menambahkan fitur daripada menghapusnya. Setelah Anda mengizinkan komentar bersarang dan ada program di luar sana yang menggunakannya, Anda tidak akan dapat mengeluarkannya tanpa merusak kompatibilitas.

alexrs
sumber
1
+1 untuk "lebih mudah untuk menambahkan fitur daripada menghapusnya".
R ..
3
setelah Anda melarang komentar yang bersarang, Anda tidak dapat memperbolehkannya juga karena komentar itu akan pecah:/*/**/
RiaD
2

Salah satu alasan yang mungkin adalah bahwa komentar bersarang harus ditangani oleh parser, karena rasa ekspresi reguler yang biasa digunakan dalam lexer tidak mendukung rekursi. Yang sederhana dapat dihilangkan sebagai ruang kosong oleh lexer, jadi mereka lebih mudah diimplementasikan dengan cara itu.

hammar
sumber
3
Itu bukan "rasa". Kata "reguler" dalam ekspresi reguler secara inheren tidak termasuk rekursi.
R ..
3
@ R: Dalam matematika, tentu saja. Tetapi dalam pemrograman, kami memiliki hal-hal yang kami sebut regex yang mendukung rekursi.
amara
Pertanyaannya adalah: Apakah ini bahkan masalah? Sebagian besar bahasa sudah harus berurusan dengan tanda kurung bersarang. Untuk beberapa nama: Lisp, C, Java, Python, Ruby, Perl.
Thomas Eding
Tanda kurung bersarang baik-baik saja, karena hal-hal di dalam tanda kurung sama dengan yang ada di luar: tanda normal. Dalam komentar, Anda tidak memiliki token, Anda hanya memiliki teks. Anda harus dapat mencocokkan token komentar awal dan akhir sehingga Anda tahu apakah 'int' adalah tipe atau hanya kata dalam komentar. (Terutama jika Anda menghilangkan komentar dalam lexer.)
Alan Shutko
2
@ThePopMachine: Saya yakin dengan apa yang saya nyatakan, bahwa regular memiliki makna formal yang ditentukan, bukan arti yang Anda gunakan, dan bahwa "regular" dalam "ekspresi reguler" dipilih untuk makna ini. Menjadi non-rekursif adalah salah satu hasil dari definisinya.
R ..
-1

Siapa tahu? Saya kira karena mendukung komentar bersarang lebih banyak pekerjaan - Anda harus memelihara setumpuk jenis, dan karena menyulitkan tata bahasa.

Neil Butterworth
sumber
-1

Komentar bersarang berarti kerja ekstra untuk parser. Biasanya ketika Anda melihat awal komentar Anda mengabaikan semuanya sampai penanda komentar akhir. Untuk mendukung komentar bersarang, Anda juga harus menguraikan teks dalam komentar. Masalah terbesarnya adalah programmer harus berhati-hati untuk menutup semua komentar yang bersarang dengan benar atau akan menyebabkan kesalahan kompilasi. Mengimplementasikan kompiler dengan benar adalah sesuatu yang bisa dilakukan tetapi melacak komentar yang bersarang sebagai programmer cukup rentan kesalahan dan menjengkelkan.

Gus
sumber
3
-1: tidak benar. Pengurai Sane tidak bekerja seperti itu.
amara