Dilema Membaca Program bagi Programmer Pemula
Membaca kode sumber sebuah program, dari yang sederhana hingga relatif kompleks, adalah keterampilan yang harus dimiliki oleh seorang programmer. Istilah program di sini digunakan tidak hanya dalam pengertian aplikasi utuh, namun juga mencakup level segmen kode, fungsi/subrutin, pustaka atau modul yang digunakan oleh sebuah aplikasi utuh. Manfaat dari terbiasanya kita membaca program adalah semakin banyaknya sumber informasi yang dapat kita gunakan untuk memecahkan masalah. Implementasi sebuah algoritma yang memodifikasi sebentuk struktur data dalam sebuah program dapat kita adaptasikan ke dalam program yang kita buat sendiri dengan konteks dan struktur data yang sama sekali berbeda.
Terlepas dari manfaat pedagogisnya, sayangnya keterampilan ini tidak banyak diajarkan (dan setahu saya tidak pernah menjadi matakuliah tersendiri di perguruan tinggi), namun baru terasa urgensinya saat kita disodori kewajiban memodifikasi program yang ditulis dan sebelumnya dikelola oleh orang lain. Dengan hanya berbekal kode sumber dan dokumentasinya (yang, patut disayangkan, tidak selalu komprehensif), dalam keadaan seperti ini seorang programmer harus mampu melanjutkan pengelolaan program tersebut tanpa menghancurkan organisasi kode yang telah ada atau menambah kompleksitas yang tidak perlu ada. Di sisi lain keadaan ini akan jarang ditemui oleh rata-rata programmer; karena lebih sering penulis asli dari program itulah yang harus melanjutkan pengelolaan, setelah memindahkan perhatian pada hal lain selama beberapa waktu.
Karenanya dapat disimpulkan bahwa secara umum, keterampilan yang harus dimiliki seorang programmer terkait dengan komprehensi kode sumber program, dengan derajat urgensi menurun, adalah:
Memahami kode sumber yang ditulis sendiri pada saat ia tidak lagi mengingat detail mekanisme dari program tersebut,
Melanjutkan pengelolaan, menyesuaikan, mengembangkan dan (bila perlu) merombaknya untuk menyesuaikan program dengan kebutuhan pengguna tanpa mengorbankan kemudahan perawatan di masa mendatang,
Memiliki kemampuan sebagaimana dijelaskan dalam point 1. dan 2. untuk program yang ditulis dan didokumentasikan oleh programmer lain,
Membaca program untuk memperkaya perkakas yang dimiliki seorang programmer untuk memecahkan masalah.
Dengan menetapkan keempat kemampuan di atas sebagai target yang harus dicapai oleh seorang programmer, salah satu pertanyaan terpenting adalah: “Bagaimana seharusnya seseorang melatih diri agar dapat terbiasa membaca program, dan mampu memahaminya dengan relatif mudah?” Paparan berikut ini didasarkan pada pengalaman penulis sendiri dan, meskipun tidak berpretensi sebagai solusi yang dapat diterapkan untuk berbagai situasi, setidaknya dapat dijadikan sedikit bahan pertimbangan, dan disesuaikan oleh pembaca dengan keadaan yang tengah dihadapi.
Memilih Program yang Akan Dibaca
Tidak setiap saat seseorang mendapatkan keleluasaan memilih
program yang akan dibaca. Gerakan open source sekali lagi
mendapat nilai positif dalam bidang ini. Permasalahannya, proliferasi
kode sumber program-program open source populer tidak selalu
diimbangi dengan dokumentasi yang memadai, dan tidak semua program
ditulis dengan programmer pemula sebagai audiens utama; membaca
program dengan kompleksitas medium-pun dapat cukup sukar dilakukan
oleh seorang pemula. Sebagai contoh, implementasi STL C++ yang
digunakan DJGPP, libgpp,
berisi dokumentasi internal (komentar inline, selain file-file .info)
yang jauh lebih memadai, dan karenanya lebih mudah dipahami dengan
hanya bergantung pada kode sumber, dibandingkan implementasi
SGI atau STLPort.
Bandingkan segmen kode berikut dalam libgpp:
|
stl_algo.h |
|---|
/**
* @brief Find the median of three values.
* @param a A value.
* @param b A value.
* @param c A value.
* @return One of @p a, @p b or @p c.
*
* If @c {l,m,n} is some convolution of @p {a,b,c} such that @c l<=m<=n
* then the value returned will be @c m.
* This is an SGI extension.
* @ingroup SGIextensions
*/
template<typename _Tp>
inline const _Tp&
__median(const _Tp& __a, const _Tp& __b, const _Tp& __c)
{
// concept requirements
__glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
if (__a < __b)
if (__b < __c)
return __b;
else if (__a < __c)
return __c;
else
return __a;
else if (__a < __c)
return __a;
else if (__b < __c)
return __c;
else
return __b;
}
|
Dengan fungsi yang sama dalam STLPort:
|
_algo.c |
|---|
template <class _Tp>
# if !(defined (__SUNPRO_CC) && (__SUNPRO_CC < 0x420 ))
inline
# endif
const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) {
if (__a < __b)
if (__b < __c)
return __b;
else if (__a < __c)
return __c;
else
return __a;
else if (__a < __c)
return __a;
else if (__b < __c)
return __c;
else
return __b;
}
|
STLPort memang mengikutkan sebuah dokumentasi komprehensif dalam
format HTML, namun dari aspek keseluruhan, dokumentasi libgpp jauh
lebih unggul (meski contoh yang diberikan hanya dalam header
<algorithms>, hal ini berlaku pula di hampir semua
file lain dalam pustaka tersebut). Bila Anda seorang programmer yang
belum lama mempelajari C++, kira-kira versi mana dari header di atas
yang akan lebih mudah Anda pahami?
Sebagai tambahan, berdasarkan apa yang penulis alami, selain memilih program yang fungsionalitasnya cukup menarik dan dapat dipahami, dan memilih port yang menyertakan dokumentasi memadai, point yang juga penting adalah memilih paket paling minimal atau versi yang relatif awal. Point ini penting, karena program-program dengan versi yang cukup lanjut dapat berisi banyak sekali red-tape1 dan fitur/kode tambahan yang mudah mengalihkan perhatian pembaca dari fungsionalitas utama program tersebut. Pendekatan ini sebenarnya dapat diaplikasikan untuk mempelajari program kompleks apapun: pelajari dahulu versi-versi awal, sebelum menggunakan distribusi terbaru2.
Bahasa Pemrograman dan Dokumentasi API
Meskipun mungkin dalam seumur hidup kita hanya akan memprogram dalam satu-dua bahasa saja (terutama yang fashionable dalam komunitas tertentu seperti C#, PHP atau Visual Basic), setidaknya memahami beragam bahasa pemrograman dan paradigma pemrograman yang didukung oleh masing-masing bahasa akan sangat bermanfaat dalam jangka panjang. Contoh yang sangat sederhana adalah implementasi algoritma modifikasi struktur data. Kode Prolog berikut:
push_left_subtree([Root,LeftChild|RightChild],
NewLeft,
[Root,[NewLeft,LeftChild,[]]|RightChild]).adalah kode yang sangat elegan untuk memodifikasi sebuah tree: “mendorong” sebuah node menjadi root baru dari subtree kiri lama tree tersebut. Kode ini dapat saja menjadi inspirasi pengingat atau contoh pembelajaran, misalnya, bahwa tree tidak harus diimplementasikan dengan class atau record: ia dapat pula diimplementasikan dengan array pointer, tuple, list, bahkan map. Setiap bahasa pemrograman selalu memiliki keunggulan dalam ekspresi kelas algoritma atau operasi-operasi tertentu dibandingkan dengan bahasa lainnya, seperti Prolog dengan tree dan definite-clause grammar, Scheme dengan rekursi, atau Python dengan list. Membatasi diri hanya membaca bahasa pemrograman tertentu sama saja dengan menutup mata terhadap alternatif pemecahan sebuah masalah (dalam bahasa pemrograman lain) yang terkadang lebih efisien daripada yang tengah kita gunakan.
Seiring dengan semakin populernya aplikasi web, dan kebebasan yang dimiliki siapapun untuk mengimplementasikan produknya dalam bahasa pemrograman dan platform pilihannya, kode-kode yang ringkas dan efisien namun tidak umum akan semakin sering ditemui. Fenomena ini lebih sering ditemui dalam produk eksperimental yang belum lama populer: Ruby On Rails (Ruby), Zope (Python), dan situs-situs seperti Reddit dan Yahoo! Store yang memulai hidup sebagai program Common Lisp. Contoh yang lebih mudah diakses: seberapa tertarik seseorang, apabila studi kasus implementasi sistem operasi dilakukan dengan mengulik kode sumber kernel Linux yang notabene sangat mudah dijangkau, namun sangat kompleks? Studi semacam itu akan relatif lebih mudah dan jauh lebih menarik apabila dilakukan terhadap sistem operasi yang jauh lebih kecil dan sederhana seperti TriangleOS atau MenuetOS. Satu hal yang mungkin membuat seseorang urung mencoba membacanya adalah kedua sistem operasi itu ditulis dalam bahasa assembler3.
Prolog tentu adalah contoh yang ekstrem; bahasa paling obscure yang kerap digunakan dalam aplikasi web mutakhir adalah Javascript. Tapi dalam kasus inipun point yang ingin penulis utarakan tetap valid: seberapa fasih kita membaca algoritma yang diimplementasikan dalam bahasa yang jarang kita gunakan?
Point lain yang terkait adalah ketersediaan dokumentasi API. Dari salah satu paparan Joel Spolsky mengenai keadaan dunia pemrograman saat ini, dapat disimpulkan bahwa tidak akan ada program nontrivial dengan kualitas produksi yang tidak memanfaatkan secara langsung API dari platform yang digunakan. Seberapa lancarnya kita membaca sebuah program akan sangat bergantung pula pada kelengkapan dokumentasi terkait platform yang digunakan, atau familiaritas dengan platform tersebut. Selamat berjuang memahami program Java, bila Anda tidak memiliki dokumentasi Java SDK.
Literate Programming
Terlepas dari berbagai masalah yang harus dipertimbangkan dalam penerapannya, membaca program-program yang ditulis secara literer atau mencoba menuliskannya sendiri, akan sangat bermanfaat pada tahap pembelajaran tertentu. Teknik pemrograman seperti ini memang tidak dapat diterapkan untuk semua kategori program, namun seperti yang dikatakan oleh Donald Knuth sendiri, pemrograman literer menyajikan konsep-konsep yang mendasari setiap mekanisme yang digunakan dalam sebuah program secara jernih, dan mempelajarinya dapat menjadi sarana edukasi yang jauh lebih efektif ketimbang cara pemrograman yang lebih umum (tergantung keterampilan si pemrogram). Salah satu kendala terbesar dalam memanfaatkan pemrograman literer untuk membiasakan diri membaca program adalah masih sedikitnya program yang ditulis dengan cara ini.
Lain-Lain
Point-point lain akan ditambahkan bilamana diperlukan.
1Red-tape
directives adalah perintah-perintah yang bertujuan
kompatibilitas platform/kompiler. Dalam kode C, pasangan perintah
preprosesor #ifdef-#endif seringkali
digunakan sebagai red-tape directive.
2Dengan mengasumsikan, bahwa distribusi terbaru itu cukup kompleks sehingga dapat membingungkan pemula. Case-in-point: Blender! Saya cukup beruntung telah menggunakannya sejak versi 2.2. Versi terbaru (v2.4.3RC3 saat artikel ini ditulis) berisi fitur yang jauh lebih banyak dari saat pertama saya gunakan, pemula akan lebih tidak berdaya menghadapinya tanpa tutorial.
3Jangan langsung menuduh bahwa ukuran yang kecil disebabkan oleh bahasa implementasi yang low-level! Pada saat artikel ini ditulis, TriangleOS baru mencapai versi 0.0.3, dan MenuetOS versi 0.84. Fungsionalitas yang ditawarkan keduanya masih cukup minim.
All contents of this site are made by me,
Adhi Hargo, unless noted otherwise.
Seluruh halaman dalam situs ini dibuat oleh Adhi Hargo,
kecuali orangnya bilang sebaliknya.