Mengapa komentar “Why Not” diperlukan
(buttondown.com)- Komentar dapat memakai bahasa manusia yang lebih ekspresif daripada identifier, sehingga cocok untuk meninggalkan pilihan yang tidak ada di kode dan alternatif yang ditinggalkan
- “comment the why, not the what” adalah pendekatan untuk menaruh sebanyak mungkin informasi ke dalam identifier, tetapi belakangan ada kecenderungan untuk memindahkan bahkan alasannya ke nama fungsi yang panjang atau nama test
- Dalam build epub
Logic for Programmers, digunakan implementasi lambat yang mengganti 16 simbol matematika secara berurutan pada tiap string, tetapi saat ini hanya ada 25 string matematika sehingga cukup cepat - Komentar semacam ini nantinya memberi tahu bagian yang harus diperbaiki ketika string matematika bertambah menjadi ratusan dan menjadi bottleneck build, serta mencatat bahwa kode lambat itu adalah trade-off yang disengaja
- Nama fungsi atau test melekat pada apa yang benar-benar dilakukan kode, sehingga sulit untuk mendokumentasikan sendiri informasi negatif berupa alternatif yang tidak dipilih dan hal-hal yang tidak dilakukan
Informasi yang lebih mudah dimuat oleh komentar daripada kode
- Kode adalah bahasa mesin yang terstruktur, sedangkan komentar ditulis dalam bahasa manusia yang ekspresif
- “comment the why, not the what” dapat ditafsirkan sebagai anjuran untuk menaruh sebanyak mungkin informasi ke dalam identifier
- Identifier lebih mirip bahasa manusia yang terbatas di dalam kode; memang tidak bisa memuat semua “what”, tetapi dalam banyak kasus bisa memuat cukup banyak
- Belakangan, semakin banyak pandangan bahwa bahkan “why” pun bisa dimasukkan bukan ke komentar, melainkan ke nama fungsi yang panjang atau nama test case
- Codebase yang self-documenting pada umumnya menambah dokumentasi lewat penambahan identifier
- Sebagai pengecualian, ada contoh mengubah komentar menjadi logging agar kode lebih self-documenting
Apa yang ditangani komentar “Why Not”
- Informasi yang sulit diekspresikan dengan kode adalah informasi negatif
- Informasi negatif menarik perhatian pada apa yang tidak ada dalam sistem, dan mengapa alternatif tertentu tidak dipilih
- “why not” bukan menjelaskan apa yang dilakukan kode, melainkan meninggalkan catatan tentang pilihan yang tidak diambil kode dan alasannya
Kasus penggantian simbol matematika di epub
- Dalam build epub
Logic for Programmers, karena alasan teknis notasi matematika seperti\foralltidak diubah menjadi simbol seperti∀ - Untuk mengatasinya, dibuat skrip yang secara langsung mengganti token di dalam string matematika dengan simbol Unicode padanannya
- Implementasi termudah adalah memanggil
string = string.replace(old, new)untuk masing-masing dari 16 simbol matematika yang diperlukan - Cara ini tidak efisien karena tiap string dilintasi 16 kali, sementara pendekatan yang menangani semua 16 penggantian dalam satu lintasan jauh lebih kompleks
- Inti komentar yang ditinggalkan adalah sebagai berikut
- Tiap string dilintasi 16 kali
- Saat ini buku tersebut hanya punya 25 string matematika, dan sebagian besar panjangnya di bawah 5 karakter
- Jadi tetap cukup cepat
- Komentar ini menjelaskan bukan hanya “mengapa memakai kode yang lambat”, tetapi juga “mengapa tidak memakai kode yang cepat”
Penanda untuk pembaca di masa depan
- Kode lambat mungkin tidak menimbulkan masalah sekarang, tetapi bisa menjadi masalah nanti
- Jika di versi masa depan
Logic for Programmersjumlah string matematika bertambah menjadi ratusan, tahap build tersebut bisa menjadi bottleneck seluruh build - Jika penandanya ditinggalkan sekarang, nanti akan langsung jelas bagian mana yang perlu diperbaiki
- Bahkan jika kode terus berjalan tanpa masalah, komentar itu tetap melestarikan fakta bahwa penulis mengetahui trade-off tersebut
- Saat membuka lagi
epub_math_fixer.pydua tahun kemudian, tidak perlu terlalu banyak menyelidiki ulang apakah kode lambat itu berasal dari kurang mahir, kekurangan waktu, atau kesalahan - Komentar negatif meninggalkan informasi bahwa implementasi lambat itu disadari, alternatifnya telah dipertimbangkan, dan diputuskan untuk tidak dioptimalkan
Mengapa sulit digantikan dengan nama fungsi dan test
- Nama fungsi seperti
RunFewerTimesSlowerAndSimplerAlgorithmAfterConsideringTradeOffsterlalu panjang dan tetap tidak cukup menjelaskan trade-off yang sebenarnya - Jika nanti kodenya dioptimalkan, nama itu mungkin harus diubah di banyak tempat
- Masalah yang lebih besar adalah nama seperti itu tidak memberi tahu apa yang sebenarnya dilakukan fungsi tersebut, sehingga justru melemahkan sifat self-documenting
- Identifier seperti nama fungsi dan nama variabel hanya bisa memuat satu klausa informasi
- Sulit memuat sekaligus “apa yang dilakukan fungsi” dan “trade-off yang diterima fungsi” dalam satu identifier
Informasi negatif yang sulit ditinggalkan bahkan lewat test
- Bisa saja dibuat test yang me-grep blok matematika dalam buku dan gagal jika jumlahnya melebihi 80
- Tetapi test seperti itu tidak menguji
EpubMathFixeritu sendiri secara langsung - Tidak ada titik di dalam fungsi tempat test tersebut bisa dipasang
- Self-documenting menempel pada kode yang ditulis dan menjelaskan apa yang dilakukan kode tersebut
- Karena informasi negatif membahas hal-hal yang tidak dilakukan kode, pendekatan self-documenting pada dasarnya tidak cocok dengannya
Pertanyaan yang lebih luas
- Komentar “why not” dapat dilihat sebagai salah satu contoh kontrafaktual (counterfactual)
- Masih tersisa pertanyaan apakah elemen abstrak dalam komunikasi manusia pada umumnya bisa dibuat self-documenting
- Masih menjadi tanda tanya apakah informasi seperti metafora, ketidakpastian, atau klaim etis juga bisa dibuat self-documenting
1 komentar
Opini Hacker News
Saya ingat lelucon yang sepertinya pernah saya lihat di Twitter beberapa tahun lalu: “Engineer junior menulis komentar yang menjelaskan apa yang dilakukan kode, engineer menengah menulis komentar yang menjelaskan mengapa kode melakukannya seperti itu, dan engineer senior menulis komentar yang menjelaskan mengapa kode tidak ditulis dengan cara lain,” kurang lebih begitu
Sebaliknya, kalau makna bisa dibuat jelas hanya dengan nama fungsi dan variabel, saya juga pernah menulis fungsi yang cukup besar tanpa komentar
Jadi sisi dengan komentar lebih sedikit memang menang, tetapi ketika melihat codebase tanpa komentar, kita harus memeriksanya sendiri untuk membedakan apakah itu mahakarya yang dipoles indah atau kode rapuh buatan pemula
Meski terlihat seperti tambalan total, kadang-kadang memang itulah yang terbaik yang benar-benar bisa didapat
Kalau menurut saya akan berguna saat melihat kode itu lagi setahun kemudian, semuanya saya tinggalkan sebagai komentar. Biasanya tentang mengapa dan mengapa tidak bisa, dan saat kodenya rumit saya juga menulis “apa” secara singkat agar alurnya lebih mudah terlihat
Yang tidak berguna adalah komentar wajib. API publik memang harus didokumentasikan dengan memadai, tetapi ada organisasi yang memaksa semua fungsi, bahkan fungsi private, diberi komentar, sampai tujuannya terlalu jelas dan hanya mengulang nama fungsi. Ini bukan hanya membuang waktu, tetapi juga membuat orang kebal terhadap komentar dan mengajarkan kebiasaan mengabaikannya
Saya juga tidak suka komentar mubazir yang ditambahkan tool. Misalnya menempelkan
//foratau//trypada setiap loop, itu sangat tidak saya sukaLebih baik menghapus komentar wajib dan komentar hasil generasi, lalu pada tema gelap mengubah komentar menjadi warna neon terang agar menonjol. Jika ada komentar, itu seharusnya berarti penting
Untuk memelihara sistem besar yang sudah tua dalam lingkungan bisnis dengan jadwal ketat, kadang kita harus melakukan hal-hal aneh, dan saat itu kita perlu menjelaskan alasannya
Alasan besar menentang komentar adalah karena komentar juga menjadi bagian dari kode dan perlu dipelihara. Namun kebanyakan orang hanya membaca komentar ketika mereka buntu, dan editor juga membuat komentar abu-abu pudar sehingga secara psikologis tidak terlihat. Karena itu komentar mudah kedaluwarsa
Saya penasaran apakah konteks untuk “diri saya di masa depan” juga berguna dalam codebase bersama yang disentuh banyak developer, atau apakah itu hanya bekerja baik ketika hanya sedikit orang yang menyentuh kode
Jadi saya menambahkan “=> yes!” pada komentar yang ada, dan berterima kasih kepada diri saya di masa lalu karena telah mendokumentasikan pertanyaan itu. Di pekerjaan, terutama saat memperbaiki bug, saya sering meninggalkan satu-dua baris komentar di atas perubahan yang tidak jelas, bersama nomor tiket
Format komentar favorit yang pernah saya tinggalkan di kode adalah template ini: “DEAR MAINTAINER: Kode ini dibuat seperti ini karena [alasan]. Jika Anda mencoba ‘memperbaikinya’ lalu menyadari bahwa itu kesalahan mengerikan, tolong naikkan counter
total_hours_wasted_here = nsebagai peringatan untuk orang berikutnya”Saya bukan pembuat aslinya, tetapi pernah menggunakannya dengan rasa syukur satu-dua kali, dan lucu melihat commit satu baris yang hanya menaikkan counter
Engineer yang lebih senior mengambil alih codebase dan “memperbaiki” semuanya menjadi gaya loop, lalu mencoba menguliahi saya lewat email tentang mengapa rekursi itu buruk, tetapi kodenya tidak benar-benar memenuhi semua requirement dan akhirnya pada dasarnya membuat ulang hal-hal yang dulu saya lakukan dengan rekursi
Belakangan dia memang meminta maaf atas sebagian ucapannya, tetapi kalau saya menaruh komentar seperti ini di bagian paling atas, mungkin seluruh kejadian itu bisa dihindari
Saya setuju judulnya ambigu, dan justru itu membuat saya membaca tulisannya. Secara pribadi saya cenderung lebih suka memakai sedikit komentar secara keseluruhan, tetapi komentar penjelas yang disebut dalam tulisan itu jelas bernilai. Ini pengingat bagus untuk menjelaskan mengapa dibuat begitu, dan mengapa bukan cara lain
Ini terutama berlaku pada kode sendiri yang masih harus dipelihara 5, 10, 15 tahun kemudian. Baru-baru ini saat meninjau kode baru dari rekan kerja, saya berpikir “kenapa dibuat begini?”, lalu 10 baris di atasnya ada alasan yang persis sama yang saya tulis 8 tahun lalu. Rekan itu mengikuti aturan inti pemeliharaan, yaitu membuatnya terlihat seperti kode yang sudah ada
Ini hanyalah kasus khusus dari prinsip yang lebih luas: beri komentar pada hal-hal yang mengejutkan saat membaca kode
Saat menulis kode, orang yang terus bertanya dalam kepala “apakah nanti saya bisa memahami kode ini?” dan setiap kali secara naluriah menjawab “ya” itu sombong dan sering keliru. Jika jawabannya “belum tentu”, pertanyaan berikutnya secara alami adalah “mengapa?”, dan jawabannya adalah hal yang harus ditulis dalam komentar
Kadang jawabannya adalah “karena pembaca mungkin bertanya-tanya mengapa tidak ditulis dengan cara lain”, dan itulah kasus khusus yang dibahas tulisan ini. Namun kadang jawabannya adalah “karena tidak jelas bagaimana ini bekerja atau mengapa ini benar”, dan saat itu diperlukan jenis komentar lain
Hal seperti ini biasanya terjadi saat memotong string atau menelusuri struktur data yang tidak biasa sebagai tahap perantara
Identifier saja bisa membawa kita sangat jauh, tetapi tidak bisa sampai tuntas. Secara pribadi, saya cenderung suka mewajibkan komentar dokumentasi seperti jsdoc/xmldoc untuk method publik, variabel, field, dan parameter
Memberi nama method dengan baik memang penting, tetapi mencoba menuliskan secara singkat apa yang dilakukannya membuatnya lebih jelas, dan terutama menyingkap cacat yang jelas. Sering kali begitu menulis kalimat pertama, nama yang lebih baik langsung terpikir; dan jika penjelasannya mulai memuat kata “dan”, itu sinyal bahwa method tersebut melakukan terlalu banyak hal dan bisa dipecah secara lebih logis
Properti mudah dianggap terlalu jelas sehingga tidak perlu dokumentasi, tetapi sesuatu seperti
/** The API key */ string ApiKey;terlalu banyak kekurangannya. Kita tidak tahu kunci ini berasal dari mana, apakah hanya untuk internal atau dipertukarkan dengan sistem eksternal, apakah wajib, apakah boleh null atau kosong, apakah ada panjang maksimum, apa yang terjadi jika nilainya tidak valid, atau apakah ada kode atau dokumen lain yang perlu dibacaBagi penulis asli, informasi ini bisa ditulis dalam 1–2 menit, tetapi bagi orang baru, saat harus mengubah atau menggunakannya, atau saat ditugaskan memperbaiki bug bertahun-tahun kemudian, bisa perlu berjam-jam untuk mengetahuinya
Dalam code review, jika saya bisa menebak apa yang akan dikatakan reviewer yang terlalu cerewet, saya sering menulis komentar seperti “tidak melakukan X karena Y”. Tujuannya mengurangi bolak-balik diskusi yang merepotkan
Komentar seperti “kita mengiterasi setiap string 16 kali, tetapi sejauh ini hanya ada 25 string formula di buku dan kebanyakan kurang dari 5 karakter, jadi ini cukup cepat” juga punya variasi lain
Yaitu memasang log debug yang aktif ketika input menjadi jauh lebih besar daripada batasan desain awal. Pesannya hampir sama untuk developer masa depan, tetapi bisa ditemukan lebih cepat sehingga waktu diagnosis dan debugging berkurang lebih banyak
Dalam sistem logging dan observability yang ideal, semua komponen aplikasi akan diukur waktunya dan sering meninggalkan informasi debug, tetapi siapa yang benar-benar memakai sistem sesempurna itu? Upaya memasang log secara spesifik di bagian yang kelak bisa memburuk performanya atau yang belum sempat dioptimalkan lebih penting
Kalau dipikir-pikir, ini ide yang obvious, tetapi selama ini pendekatannya adalah meninggalkan komentar di tempat yang perlu dilihat lagi nanti, lalu berharap kita mengingat komentar itu ketika keadaan memburuk
Apa pun kata orang, saya banyak menulis komentar dan doc comment di berbagai bagian kode. Namun pendekatannya dibalik: pertama-tama saya menulis daftar tahapan aplikasi secara kasar sebagai komentar, lalu selama pengembangan saya memecah langkah besar menjadi langkah kecil, kadang menghapus komentar awal, kadang membiarkannya, dan terus merincinya sampai hampir menjadi algoritme yang selesai
Biasanya saya mengode dari luar ke dalam, jadi sambil memecah komentar saya juga menulis kodenya. Kadang saya mengode sekaligus dulu, lalu belakangan menambahkan komentar sampai tingkat yang mungkin dianggap merepotkan oleh kebanyakan orang. Saya memberi penjelasan pada semua fungsi dan variabel, bahkan fungsi
deg_to_radpun saya beri"""Converts degrees to radians.""". Toh ruang penyimpanan murahSaya tahu kebanyakan orang tidak menyukainya, tapi tidak masalah. Kalau tidak suka melihatnya, hapus saja dengan skrip atau saat code review. Meski begitu, membaca kode lama saya sendiri jauh lebih menyenangkan daripada kode orang lain tanpa komentar. Di Python, kode boilerplate sederhana seperti Flask API umumnya cukup self-documenting, tetapi justru boilerplate semacam itu sering banyak berubah sehingga bisa memiliki komentar penting. Di industri, bagian algoritme lebih sering ditulis ulang seluruhnya
Saya akan tetap menyukai komentar dan doc comment ke depannya
Saya suka membuat konseptualisasi menyeluruh di kepala, dan pada tahap awal saya merasa lambat kalau harus bereksperimen dengan benar-benar mencoba berbagai pilihan desain. Jadi begitu pilihan desain ditetapkan, itu harus didokumentasikan. Karena orang lain belum bisa mengakses isi kepala saya
Untuk detailnya, saya berharap akan menjadi lebih jelas setelah orang lain juga selesai mengonsepkannya. Namun kalau karena suatu alasan konseptualisasi itu tidak terjadi, kodenya bisa menjadi lebih sulit dibaca, jadi saya memolesnya lagi agar setidaknya keterbacaan dasarnya tetap terjaga
Memperbarui komentar sering kali menjadi pekerjaan tersendiri, sama seperti memperbaiki kode. Jadi secara realistis, komentar biasanya adalah sesuatu yang menunggu untuk menjadi kebohongan. Pada akhirnya komentar dan kode menjadi tidak selaras, dan itu bisa lebih buruk daripada kode tanpa komentar
Lebih baik tes otomatis yang menunjukkan intent. Tes pada umumnya tidak bisa berbohong, karena kalau tidak demikian tentu tidak akan di-merge. Jika ada sekumpulan tes yang cukup baik yang menunjukkan bagaimana kode dimaksudkan untuk digunakan, saya ingin melihatnya, karena itu bersifat menjelaskan sekaligus hampir dijamin benar
Itu sangat membantu ketika harus melihatnya lagi 5 minggu kemudian
Saya mengikuti konsep “komentar adalah permintaan maaf kepada diri sendiri di masa depan”
Kalau kodenya aneh atau lambat, atau ada bagian yang ketika dijelaskan kepada seseorang membuat saya berkata “ini memang agak berantakan”, biasanya saya meninggalkan komentar. Terutama jika saya pernah mencoba mengubahnya sebelumnya, saya mendokumentasikan kasus yang tidak berhasil, apa yang diperbaiki, dan sebagainya
Dengan pendekatan kriteria seperti ini, komentar yang tidak perlu akan hilang dengan sendirinya, dan biasanya kita hanya mendokumentasikan mengapa ketika memang benar-benar diperlukan. Cobalah sekitar sebulan di codebase sendiri, nanti akan terasa