Nasihat “selera baik” Brian Kernighan menunjukkan bagaimana kode yang mudah dibaca menghemat waktu, mengurangi bug, dan membantu tim nyata bergerak lebih cepat daripada trik cerdik.

Nama Brian Kernighan muncul di tempat-tempat yang banyak pengembang gunakan tanpa memikirkannya: alat Unix klasik, ekosistem C, dan tulisan serta ceramah puluhan tahun yang mengajarkan orang cara menjelaskan program dengan jelas. Entah Anda mengingat The C Programming Language (bersama Dennis Ritchie), The Unix Programming Environment, atau esai dan pidatonya, benang merahnya adalah tuntutan pada ide-ide sederhana yang diekspresikan dengan rapi.
Nasihat terbaik Kernighan tidak bergantung pada sintaks C atau konvensi Unix. Ini tentang bagaimana manusia membaca: kita memindai untuk struktur, mengandalkan penamaan, menafsirkan niat, dan bingung ketika kode menyembunyikan makna di balik trik. Itulah sebabnya “selera” dalam keterbacaan tetap penting saat Anda menulis TypeScript, Python, Go, Java, atau Rust.
Bahasa berubah. Alat membaik. Tim tetap merilis fitur di bawah tekanan waktu, dan sebagian besar kode dipelihara oleh orang lain selain penulis aslinya (sering kali kamu di masa depan). Kejelasan adalah pengganda yang membuat semua itu bisa bertahan.
Ini bukan penghormatan untuk “hero coding” atau panggilan untuk menghafal aturan jadul. Ini panduan praktis untuk kebiasaan yang membuat kode sehari-hari lebih mudah dikerjakan:
Pengaruh Kernighan penting karena menunjuk pada tujuan sederhana dan ramah-tim: tulis kode yang berkomunikasi. Ketika kode dibaca seperti penjelasan yang jelas, Anda menghabiskan lebih sedikit waktu untuk mendekode dan lebih banyak waktu untuk memperbaikinya.
“Selera baik” dalam keterbacaan kode bukan soal gaya personal, pola mewah, atau memadatkan solusi ke baris paling sedikit. Ini adalah kebiasaan memilih opsi paling sederhana yang jelas dan secara andal mengkomunikasikan niat.
Solusi dengan selera baik menjawab pertanyaan dasar untuk pembaca berikutnya: Apa yang coba dilakukan kode ini, dan mengapa dilakukan seperti ini? Jika jawaban itu membutuhkan gimnastik mental, asumsi tersembunyi, atau memecahkan trik, kode itu menghabiskan waktu tim.
Sebagian besar kode dibaca jauh lebih sering daripada ditulis. “Selera baik” memperlakukan membaca sebagai aktivitas utama:
Itu sebabnya keterbacaan bukan sekadar estetika (indentasi, lebar baris, atau apakah Anda suka snake_case). Itu membantu, tetapi “selera baik” terutama tentang membuat penalaran mudah: nama yang jelas, alur kontrol yang mudah, dan struktur yang dapat diprediksi.
Kesalahan umum adalah mengoptimalkan untuk singkat daripada kejelasan. Kadang kode paling jelas sedikit lebih panjang karena membuat langkah-langkah menjadi eksplisit.
Contohnya, bandingkan dua pendekatan:
Versi kedua mungkin menambah baris, tetapi mengurangi beban kognitif yang dibutuhkan untuk memverifikasi kebenaran. Ini juga membuat bug lebih mudah diisolasi dan perubahan lebih aman diterapkan.
Selera baik adalah tahu kapan berhenti “meningkatkan” solusi dengan kecerdikan dan sebaliknya membuat niat menjadi jelas. Jika rekan dapat memahami kode tanpa meminta penjelasan, Anda telah memilih dengan baik.
Kode cerdik sering terasa kemenangan sesaat: baris lebih sedikit, trik rapi, faktor “wow” di diff. Di tim nyata, kecerdikan itu berubah menjadi tagihan berulang—dibayar dengan waktu onboarding, waktu review, dan keraguan setiap kali seseorang harus menyentuh kode lagi.
Onboarding melambat. Rekan baru tidak hanya perlu mempelajari produk; mereka juga harus mempelajari dialek pribadi Anda dari jalan pintas. Jika memahami sebuah fungsi memerlukan decode operator cerdik atau konvensi implisit, orang akan menghindari mengubahnya—atau mengubahnya dengan rasa takut.
Review menjadi lebih panjang dan kurang andal. Reviewer menghabiskan energi membuktikan trik itu benar daripada menilai apakah perilaku cocok dengan niat. Lebih buruk, kode cerdik lebih sulit disimulasi secara mental, sehingga reviewer melewatkan edge case yang sebenarnya akan mereka tangkap pada versi yang jelas.
Kecerdikan menumpuk selama:
Beberapa pelaku berulang:
17, 0.618, -1) yang mengkode aturan yang tak ada yang ingat.&& / ||) yang mengandalkan pembaca tahu aturan evaluasi yang halus.Inti pesan Kernighan tentang “selera” muncul di sini: kejelasan bukan soal menulis lebih banyak; ini soal membuat niat menjadi jelas. Jika versi “pintar” menghemat 20 detik hari ini tapi menambah 20 menit untuk setiap pembaca di masa depan, itu bukan pintar—itu mahal.
“Selera” Kernighan sering muncul dalam keputusan kecil dan bisa diulang. Anda tidak perlu rewrite besar untuk membuat kode lebih mudah diurus—kemenangan kecil untuk kejelasan menumpuk setiap kali seseorang memindai berkas, mencari perilaku, atau memperbaiki bug di bawah tekanan waktu.
Nama yang baik mengurangi kebutuhan komentar dan membuat kesalahan lebih sulit disembunyikan.
Tujuannya nama yang mengungkapkan maksud yang sesuai dengan cara tim Anda berbicara:
invoiceTotalCents daripada sum.Jika sebuah nama memaksa Anda mendekodenya, ia melakukan kebalikan dari tugasnya.
Sebagian besar membaca adalah pemindaian. Spasi dan struktur yang konsisten membantu mata menemukan apa yang penting: batas fungsi, kondisional, dan “jalur bahagia.”
Beberapa kebiasaan praktis:
Saat logika menjadi rumit, keterbacaan biasanya meningkat dengan membuat keputusan eksplisit.
Bandingkan dua gaya ini:
// Sulit dipindai
if (user && user.active && !user.isBanned && (role === 'admin' || role === 'owner')) {
allow();
}
// Lebih jelas
if (!user) return deny('missing user');
if (!user.active) return deny('inactive');
if (user.isBanned) return deny('banned');
if (role !== 'admin' && role !== 'owner') return deny('insufficient role');
allow();
Versi kedua lebih panjang, tetapi dibaca seperti daftar periksa—dan lebih mudah diperluas tanpa merusak.
Ini adalah pilihan “kecil”, tetapi adalah kerajinan harian kode yang dapat dipelihara: nama yang jujur, format yang membimbing pembaca, dan alur kontrol yang tidak membuat Anda melakukan gimnastik mental.
Gaya kejelasan Kernighan paling terlihat pada bagaimana Anda memecah pekerjaan menjadi fungsi dan modul. Pembaca harus bisa memindai struktur, menebak apa yang dilakukan tiap bagian, dan sebagian besar benar sebelum membaca detail.
Usahakan fungsi melakukan persis satu hal pada satu “tingkat zoom”. Ketika sebuah fungsi mencampur validasi, aturan bisnis, format, dan I/O, pembaca harus mengingat banyak benang sekaligus.
Tes cepat: jika Anda menulis komentar seperti “// sekarang lakukan X” di dalam fungsi, X seringnya kandidat bagus untuk fungsi terpisah dengan nama yang jelas.
Daftar parameter panjang adalah pajak kompleksitas tersembunyi: setiap situs pemanggil menjadi semacam file konfigurasi mini.
Jika beberapa parameter selalu berjalan bersama, kelompokkan dengan bijak. Object opsi (atau struktur data kecil) bisa membuat situs pemanggil menjadi jelas—jika Anda menjaga grupnya koheren dan menghindari memasukkan semuanya ke satu kantung “misc”.
Juga, lebih suka meneruskan konsep domain daripada primitif. UserId lebih baik daripada string, dan DateRange lebih baik daripada (start, end) saat nilai-nilai itu punya aturan.
Modul adalah janji: “Semua yang Anda butuhkan untuk konsep ini ada di sini, dan sisanya ada di tempat lain.” Jaga modul cukup kecil sehingga Anda bisa memegang tujuan mereka di kepala, dan desain batas yang meminimalkan efek samping.
Kebiasaan praktis yang membantu:
Saat Anda perlu state bersama, beri nama dengan jujur dan dokumentasikan invariansnya. Kejelasan bukan tentang menghindari kompleksitas—tetapi menempatkannya di tempat pembaca mengharapkannya. Untuk lebih lanjut tentang menjaga batas-batas ini selama perubahan, lihat /blog/refactoring-as-a-habit.
Selera Kernighan tampak pada cara Anda memberi komentar: tujuannya bukan untuk memberi anotasi setiap baris, melainkan mengurangi kebingungan di masa depan. Komentar terbaik mencegah asumsi yang salah—terutama saat kode benar tetapi mengejutkan.
Komentar yang mengulang kode (“increment i”) menambah kekacauan dan melatih pembaca mengabaikan komentar. Komentar yang berguna menjelaskan niat, pertukaran, atau batasan yang tidak jelas dari sintaks.
# Buruk: menyatakan apa yang sudah terlihat di kode
retry_count += 1
# Baik: menjelaskan mengapa retry dibatasi
retry_count += 1 # Menghindari banned akibat throttling pada kegagalan berulang
Jika Anda tergoda menulis komentar “apa”, seringkali tanda bahwa kode harus dibuat lebih jelas (nama lebih baik, fungsi lebih kecil, alur kontrol lebih sederhana). Biarkan kode membawa fakta; biarkan komentar membawa alasan.
Tidak ada yang merusak kepercayaan lebih cepat daripada komentar basi. Jika sebuah komentar opsional, ia akan melenceng dari waktu ke waktu; jika salah, ia menjadi sumber bug aktif.
Kebiasaan praktis: perlakukan pembaruan komentar sebagai bagian dari perubahan, bukan “bagus jika ada”. Saat review, wajar untuk menanyakan: Apakah komentar ini masih sesuai dengan perilaku? Jika tidak, perbarui atau hapus. “Tanpa komentar” lebih baik daripada “komentar salah.”
Komentar inline untuk kejutan lokal. Panduan yang lebih luas cocok di docstring, README, atau catatan pengembang—terutama untuk:
Docstring yang baik memberi tahu seseorang cara menggunakan fungsi dengan benar dan error apa yang diharapkan, tanpa menceritakan implementasi. Catatan pendek di /docs atau /README bisa menangkap cerita “mengapa kami melakukannya seperti ini” sehingga ia bertahan lewat refactor.
Kemenangan sunyi: lebih sedikit komentar, tetapi tiap komentar pantas ada.
Sebagian besar kode terlihat “baik” pada jalur bahagia. Uji selera yang sebenarnya adalah apa yang terjadi ketika input hilang, layanan timeout, atau pengguna melakukan sesuatu tak terduga. Saat tertekan, kode cerdik cenderung menyembunyikan kebenaran. Kode yang jelas membuat kegagalan menjadi jelas—dan dapat dipulihkan.
Pesan error adalah bagian dari produk dan alur debugging Anda. Tulis seolah orang berikutnya yang membacanya lelah dan sedang on-call.
Sertakan:
Jika Anda punya logging, tambahkan konteks terstruktur (seperti requestId, userId, atau invoiceId) sehingga pesan bisa ditindaklanjuti tanpa menggali data yang tidak relevan.
Ada godaan untuk “menangani semua” dengan one-liner cerdik atau catch-all generik. Selera baik adalah memilih beberapa edge case yang penting dan menampakkannya.
Misalnya, cabang eksplisit untuk “input kosong” atau “tidak ditemukan” seringkali lebih mudah dibaca daripada rantai transformasi yang secara implisit menghasilkan null di suatu tempat. Saat kasus khusus penting, beri nama dan taruh di depan.
Mencampur bentuk return (kadang objek, kadang string, kadang false) memaksa pembaca menyimpan pohon keputusan mental. Pilih pola yang konsisten:
Penanganan kegagalan yang jelas mengurangi kejutan—dan kejutan adalah tempat munculnya bug dan panggilan tengah malam.
Kejelasan bukan hanya tentang maksud Anda saat menulis kode. Ini tentang apa yang orang berikutnya harapkan lihat saat membuka berkas jam 16:55. Konsistensi mengubah “membaca kode” menjadi pengenalan pola—lebih sedikit kejutan, lebih sedikit salah paham, lebih sedikit perdebatan yang muncul setiap sprint.
Panduan tim yang baik singkat, spesifik, dan pragmatis. Ia tidak mencoba mengkodekan setiap preferensi; ia menyelesaikan pertanyaan yang berulang: konvensi penamaan, struktur file, pola penanganan error, dan apa arti “selesai” untuk tes.
Nilai sosialnya nyata: mencegah diskusi yang sama berulang tiap PR. Saat sesuatu tertulis, review bergeser dari “Saya lebih suka X” menjadi “Kita sudah setuju X (dan ini alasannya).” Jaga agar panduan tersebut hidup dan mudah ditemukan—banyak tim meletakkannya di repo (mis. /docs/style-guide.md) agar dekat dengan kode.
Gunakan formatter dan linter untuk hal yang dapat diukur dan membosankan:
Ini membebaskan manusia fokus pada makna: penamaan, bentuk API, edge case, dan apakah kode sesuai dengan niat. Aturan manual masih penting ketika mereka menjelaskan pilihan desain—mis. “Pilih return awal untuk mengurangi nesting” atau “Satu titik masuk publik per modul.” Alat tidak bisa menilai itu sepenuhnya.
Kadang kompleksitas dibenarkan: batasan performa ketat, constraint embedded, konkurensi rumit, atau perilaku spesifik platform. Kesepakatan seharusnya: pengecualian diperbolehkan, tetapi harus eksplisit.
Standar sederhana membantu: dokumentasikan pertukaran dalam komentar singkat, tambahkan micro-benchmark atau pengukuran saat performa dikutip, dan isolasi kode kompleks di balik antarmuka jelas sehingga sebagian besar basis kode tetap bisa dibaca.
Review kode yang baik terasa bukan seperti inspeksi tetapi lebih seperti pelajaran singkat terfokus tentang “selera baik.” Inti Kernighan bukan bahwa kode cerdik itu jahat—tetapi kecerdikan mahal saat orang lain harus hidup dengannya. Review adalah tempat tim bisa membuat pertukaran itu terlihat dan memilih kejelasan dengan sengaja.
Mulailah dengan pertanyaan: “Bisakah rekan memahami ini dalam satu kali lihat?” Biasanya itu berarti melihat penamaan, struktur, tes, dan perilaku sebelum menyelami mikro-optimisasi.
Jika kode benar tetapi sulit dibaca, perlakukan keterbacaan sebagai cacat nyata. Sarankan penggantian nama variabel untuk mencerminkan niat, memecah fungsi panjang, menyederhanakan alur kontrol, atau menambahkan tes kecil yang mendemonstrasikan perilaku yang diharapkan. Review yang menangkap “ini bekerja, tapi saya tidak tahu mengapa” mencegah kebingungan berbulan-bulan.
Urutan praktis yang bekerja baik:
Review melenceng ketika umpan balik dibingkai seperti mencetak poin. Daripada “Kenapa kamu melakukan ini?” coba:
Pertanyaan mengundang kolaborasi dan sering mengungkap kendala yang tidak Anda ketahui. Saran mengkomunikasikan arah tanpa menyiratkan inkompetensi. Nada ini adalah cara “selera” menyebar dalam tim.
Jika Anda ingin keterbacaan konsisten, jangan mengandalkan mood reviewer. Tambahkan beberapa “cek kejelasan” ke template review dan definisi selesai. Buat mereka singkat dan spesifik:
Seiring waktu, ini mengubah review dari mengawasi gaya menjadi mengajarkan penilaian—tepat disiplin sehari-hari yang dikedepankan Kernighan.
Alat LLM bisa menghasilkan kode yang bekerja dengan cepat, tetapi “bekerja” bukan tolok ukur yang Kernighan maksud—berkomunikasi adalah. Jika tim Anda memakai workflow vibe-coding (mis. membangun fitur via chat dan iterasi pada kode yang dihasilkan), layak memperlakukan keterbacaan sebagai kriteria penerimaan kelas satu.
Di platform seperti Koder.ai, di mana Anda bisa menghasilkan frontend React, backend Go, dan aplikasi Flutter dari prompt chat (dan mengekspor kode sumber setelahnya), kebiasaan yang berorientasi selera tetap berlaku:
Kecepatan paling bernilai ketika keluaran tetap mudah ditinjau, dipelihara, dan diperluas oleh manusia.
Kejelasan bukan sesuatu yang Anda “capai” sekali. Kode tetap terbaca hanya jika Anda terus mendorongnya kembali ke bahasa biasa saat kebutuhan berubah. Sentimen Kernighan cocok di sini: pilih perbaikan yang stabil dan dapat dimengerti daripada rewrite heroik atau one-liner “pintar” yang mengesankan hari ini dan membingungkan bulan depan.
Refaktoring paling aman itu membosankan: perubahan kecil yang menjaga perilaku identik. Jika Anda punya tes, jalankan setelah tiap langkah. Jika tidak, tambahkan beberapa pemeriksaan fokus di area yang Anda sentuh—anggap itu sebagai pembatas sementara agar Anda bisa memperbaiki struktur tanpa takut.
Ritme praktis:
Commit kecil juga memudahkan review: rekan bisa menilai niat, bukan berburu efek samping.
Anda tak perlu menghapus semua konstruksi “cerdik” sekaligus. Saat Anda menyentuh kode untuk fitur atau bugfix, tukarkan jalan pintas cerdik dengan ekuivalen yang jelas:
Inilah cara kejelasan menang di tim nyata: satu hotspot yang diperbaiki setiap kali, tepat di tempat orang memang bekerja.
Tidak semua pembersihan mendesak. Aturan berguna: refactor sekarang ketika kode aktif diubah, sering disalahpahami, atau berpotensi menyebabkan bug. Jadwalkan nanti ketika stabil dan terisolasi.
Buat utang refaktoring terlihat: tinggalkan TODO singkat dengan konteks, atau tambahkan tiket yang menjelaskan rasa sakitnya (“sulit menambah metode pembayaran baru; fungsi melakukan 5 tugas”). Dengan begitu Anda bisa memutuskan dengan sengaja—daripada membiarkan kode yang membingungkan perlahan menjadi pajak permanen tim.
Jika Anda ingin “selera baik” muncul konsisten, buat mudah untuk dipraktikkan. Berikut checklist ringan yang bisa Anda ulangi dalam perencanaan, penulisan kode, dan review—cukup singkat untuk diingat, cukup spesifik untuk ditindaklanjuti.
Sebelum: process(data) melakukan validasi, parsing, penyimpanan, dan logging di satu tempat.
Sesudah: Pisahkan menjadi validateInput, parseOrder, saveOrder, logResult. Fungsi utama menjadi garis besar yang mudah dibaca.
Sebelum: if not valid then return false diulang lima kali.
Sesudah: Satu bagian guard di depan (atau satu fungsi validasi) yang mengembalikan daftar masalah yang jelas.
Sebelum: x, tmp, flag2, doThing().
Sesudah: retryCount, draftInvoice, isEligibleForRefund, sendReminderEmail().
Sebelum: Loop dengan tiga kasus khusus tersembunyi di tengah.
Sesudah: Tangani kasus khusus dulu (atau ekstrak helper), lalu jalankan loop sederhana.
Pilih satu perbaikan untuk diadopsi minggu ini: “tidak ada singkatan baru,” “jalur bahagia dulu,” “ekstrak satu helper per PR,” atau “setiap pesan error menyertakan langkah selanjutnya.” Lacak selama tujuh hari, lalu pertahankan apa yang benar-benar memudahkan pembacaan.
Pengaruh Kernighan lebih sedikit tentang C dan lebih tentang prinsip yang tahan lama: kode adalah medium komunikasi.
Bahasa dan kerangka kerja berubah, tetapi tim tetap membutuhkan kode yang mudah dipindai, ditelaah, dan di-debug—terutama berbulan-bulan kemudian atau saat berada di bawah tekanan waktu.
“Selera baik” berarti konsisten memilih opsi paling sederhana yang jelas dan mengkomunikasikan niat.
Uji yang berguna: dapatkah seorang rekan menjawab “apa yang dilakukan ini, dan mengapa dilakukan demikian?” tanpa harus memecahkan trik atau bergantung pada asumsi terselubung.
Karena sebagian besar kode lebih sering dibaca daripada ditulis.
Mengoptimalkan untuk pembaca mengurangi waktu onboarding, gesekan saat review, dan risiko perubahan yang salah—terutama ketika pemelihara adalah “kamu di masa depan” dengan konteks yang lebih sedikit.
“Pajak kecerdikan” muncul sebagai:
Jika versi yang cerdas menghemat detik sekarang tapi menambah menit setiap kali disentuh, itu merugikan secara bersih.
Pola yang sering merusak pemeliharaan antara lain:
Pola-pola ini menyembunyikan keadaan menengah dan membuat edge case lebih mudah terlewat saat review.
Ketika kode yang sedikit lebih panjang mengurangi beban kognitif.
Menjadikan langkah-langkah eksplisit dengan variabel bernama (mis. validate → normalize → compute) dapat mempermudah verifikasi kebenaran, menyederhanakan debugging, dan membuat perubahan masa depan lebih aman—meskipun menambah beberapa baris.
Berusaha untuk:
invoiceTotalCents daripada sum)Jika Anda perlu mendekode nama, itu tidak menjalankan tugasnya; nama harus mengurangi kebutuhan komentar tambahan.
Utamakan percabangan sederhana yang eksplisit dan jaga “jalur bahagia” tetap terlihat.
Taktik yang biasanya membantu:
Komentar mengapa, bukan apa.
Komentar yang baik menangkap niat, pertukaran, batasan, atau invarians yang tidak jelas dari sintaks. Hindari menceritakan kode yang jelas, dan perlakukan pembaruan komentar sebagai bagian dari perubahan—komentar basi lebih berbahaya daripada tidak ada komentar.
Gunakan alat untuk aturan mekanis (formatting, import, peringatan jelas) dan serahkan penilaian makna kepada manusia.
Panduan gaya ringan menyelesaikan keputusan berulang (penamaan, struktur, pola penanganan error) sehingga review jadi tentang keterbacaan dan perilaku, bukan preferensi personal.
Jika membuat pengecualian untuk performa atau keterbatasan, dokumentasikan pertukaran tersebut dan isolasi kompleksitas di balik antarmuka yang bersih.