ASPEK IMPERATIF DALAM PENYELESAIAN PERSOALAN YANG MEMBUTUHKAN PENDEKATAN BERBEDA Aditya Rama Mitra, ST., MT dan Arnold Aribowo, ST., MT*
Abstract Programming language is made available for bridging the way people see and think of a problem and also its solution finding, with the computer capability in helping human provide solution to that problem. With various programming languages at hand, one can choose the most suitable tool for solving some problem, i.e. computer solvable problem. We see that the essence of this discussion is not one of programming language choice, but how a programmer view the problem given. In this sense, we are concerned much with programming paradigm. Indeed, language choice is a logical consequence, following a particular paradigm under which programmer's approaches are refered to. The implication of this paradigm issue leads to programmer's ability for accomodating a paradigm change need. Prior to this ability achievement, one usually, but not neccessarily, has gone through some paradigm shift experiences. These paradigms, under which programming languages are fostered, are imperative, functional, logic (declarative), and object-oriented paradigms. This paper writing is aimed to show a tendency, that we indicate carefully as an unaware situation, in which a programmer is likely to be engaged while solving some problem that actually requires a different approach from different view-point. To support our investigation, we introduce a set of different solutions, in form of program codes, of the single case, written following different paradigms, but, in fact, conceiving or reflecting imperative aspect. Keywords: paradigm, programming, programming paradigm, programming language, paradigm change, paradigm shift.
1. Pendahuluan Komputer banyak digunakan untuk membantu manusia menyelesaikan berbagai masalah (computer solvable problem) melalui bahasa yang dapat dipahaml oleh komputer. Kenyataannya, hal yang mudah dipahami oleh komputer justru merupakan hal yang sanqat sulit dipahami oleh manusia dan sebaliknya. Dalam hal inilah, bahasa pemrograman berperan untuk menjembatani cara berpikir manusia dengan kemampuan komputer untuk menyelesaikan masalah (lihat Gambar 1 2 ).
' Dosen Tetap Jurusan Teknik Komputer, FIK-UPH Aspek Imperatif... (Aditya Rama Mitra dan Arnold Aribowo)
55
Human
f Making problem-solving convenient
T Programming Language
i
Making efficient use
i
Computing Machines Gambar 1. Peranan bahasa pemrograman untuk menyelesaikan masalah
Melalui bahasa pemrograman, manusia dapat menetapkan, mengorganisasikan dan melakukan penalaran proses komputasi untuk menyelesaikan masalah [2]. Dalam perkembangannya, berbagai bahasa pemrograman telah dikembangkan, di antaranya BASIC, C, C++, C#, Pascal, Prolog, Eclipse, Haskell, LISP, Miranda dan Java. Bahasa-bahasa pemrograman ini dapat diklasifikasikan dalam banyak cara, salah satu di antaranya menurut paradigma yang mendasarinya. Menurut Sethi 2 terdapat 5 paradigma pemrograman, yaitu imperatif, fungsional, logika, berorientasi objek dan konkuren. Masing-masing paradigma pemrograman tersebut memiliki pendekatan tertentu dalam menyelesaikan masalah. Dari sekian banyak bahasa yang ada, pemilihan bahasa pemrograman merupakan suatu persoalan tersendiri. Sebelum pemilihan bahasa dilakukan, ranah dari computer solvable problem seharusnya sudah diketahui dengan tepat. Pertanyaannya kemudian, yang menarik perhatian kami, apakah di dalam menyelesaikan persoalan tersebut masih terlihat adanya indikasi kecenderungan bekerja dengan paradigma lama dalam lingkungan baru yang menuntut poaradigma berbeda. Dengan kata lain, apakah seorang pemrogram memiliki kemampuan cukup (dengan bekal pengetahuan dasar yang memadai) untuk beralih kepada cara pandang persoalan (paradigm change) berbeda dalam situasi yang mensyaratkan demikian. Kami memandang kemampuan paradigm change erat kaitannya dengan berbagai pengalaman berharga seorang pemrogram pada saat mengatasi persoalan paradigm shift (bergeser dari suatu paradigma ke paradigma lain). Persoalan paradigm change menyiratkan bahwa persoalan pemrograman bukan semata-mata memperoleh program yang berkelakuan benar dan memberi hasil seperti yang diharapkan. Kami menilai bahwa pemilihan paradigma itu jauh lebih esensial ketimbang pemilihan bahasa pemrograman yang merupakan konsekuensi logik dari pemilihan tersebut. Dalam makalahnya, Stroustrup 3 menegaskan pengertian mula (original idea) paradigma pemrograman dalam formulasi berikut: Decide which procedures you want; use the best algorithms you can find. Dalam perkembangannya, terjadi pergeseran paradigma pemrograman (paradigm shift) dari perancangan prosedur, seperti yang direfleksikan paradigma semula, mengarah kepada pengorganisasian data. Dalam hal ini, sebuah modul didefinisikan sebagai himpunan dari prosedur (procedure) yang berkaitan beserta data yang 56 Jurnal llmiah llmu Komputer, Vol. 1 No. 1 Januari 2003: 55-64
dimanipulasinya. Penghimpunan prosedur-data semacam ini, yang dikenal juga sebagai penyembunyian data (data hiding), menjadikan ukuran program (program size) membesar. Paradigma pemrograman karenanya menjadi 3 Decide which modules you want; partition the program so that data is hidden in modules. Pergeseran paradigma dalam perkembangan berikutnya ditandai dengan diperkenal-kannya konsep tentang abstraksi data. Pemikiran ini sendiri berawal dari gagasan tentang sentralisasi semua data bertipe sama di bawah kendali suatu modul pengelola tipe (type manager module). Sementara pendefinisian modul diketahui merupakan bagian dari aktivitas pemrograman dengan modul (programming with modules). Jadi, hingga sejauh ini konsep-konsep baru yang diperkenalkan masih memperlihatkan tautannya dengan landasan terdahulu. Dalam penjelasannya, konsep baru tersebut menjadi sebuah paradigma baru. Paradigma pemrograman dimaksud adalah 3: Decide which types you want; provide a full set of operations for each type. Persoalan dengan abstraksi data ialah bahwa konsep ini tidak mendukung gagasan tentang kemampuan membedakan sifat umum (general properties, commonality) sebarang objek (contoh: sebarang objek geometri mempunyai warna, mempunyai dimensi) dengan sifat khusus suatu objek (contoh: sebuah bujur sangkar mempunyai panjang dan lebar yang sama). Sebagai akibatnya terjadinya pergeseran paradigma kembali. Paradigma baru ini dikenal sebagai paradigma berorientasi objek. Pada dasarnya paradigma ini mengatakan 3: Decide which classes you want; provide a full set of operations for each class; make commonality explicit by using inheritance. 2. Beberapa bahasa pemrograman berdasarkan paradigma yang mendasarinya Idealnya, sebuah bahasa pemrograman dapat diklasifikasikan menurut kelas paradigma pemrograman secara unik. Artinya, setiap bahasa pemrograman memiliki satu payung paradigma tunggal. Sekalipun demikian beberapa orang cenderung mengklasifikasikan C++ ke dalam kelas yang berbeda: kelompok bahasa pemrograman imperatif dan sekaligus kelompok bahasa berorientasi objek. Menurut versi ini, C++ masuk dalam kategori bahasa hibrid imperatif/berorientasi objek. Pada kenyataannya, C++ adalah superset dari C dan bahkan terdapat banyak program C++ yang dituliskan dalam gaya imperatif dengan objek-objek yang berperan sebagai variabel. Dalam kasus C++ ini, secara ekstrem dapat dikatakan bahwa kekuatan dari berbagai fitur C++ akan lenyap jika seorang pemrogram tetap mempertahankan pengetahuan dan kebiasaan pemrograman C-nya dalam lingkungan yang "baru". Menurut MacLennan1, program adalah sebuah spesifikasi komputasi; sedangkan bahasa pemrograman adalah notasi yang digunakan -untuk mendeskripsikan program. Bahasa pemrograman tidak hanya berfungsi menjadikan program seseorang yang ditulis dalam bahasa tersebut dapat dimengerti dan dieksekusi Aspek Imperatif... (Aditya Rama Mitra dan Arnold Aribowo)
57
komputer, tetapi lebih jauh seharusnya juga dapat menjelaskan program itu, baik ke penulis program itu sendiri maupun ke orang lain. Jika pada kenyataannya pemrogram menghabiskan banyak waktu untuk membaca program yang ia tulis sendiri, maka ini mengindikasikan kerumitan bahasa, jika tidak kemungkinan adanya masalah dengan programming style. Dalam kemungkinan pertama, makin mudah suatu bahasa dimengerti oleh komputer, ternyata makin sulit bahasa tersebut bagi manusia. Salah satu karakteristik bahasa pemrograman adalah bersifat umum (universal). Dalam hal ini dimaksudkan bahwa setiap persoalan yang dapat diselesaikan oleh komputer (computer solvable) harus mempunyai solusi tertentu yang dapat dinyatakan (expressible) dalam bahasa tersebut. Berdasarkan karakteristik ini, MacLennan1 mendefinisikan bahasa pemrograman secara lebih formal sebagai berikut: 'A programming language is a language that is intended for the expression of computer programs and that is capable of expressing any computer program' Persyaratan yang dipenuhi sebuah bahasa pemrograman adalah bahwa bahasa tersebut: • • •
Memiliki ekspresi alami (natural expressivity) Dapat diimplementasikan di komputer Mempunyai kemampuan untuk diimplementasi secara efisien (acceptably efficient implementation)
Bahasa pemrograman jelas berkaitan erat dengan isu tentang paradigma pemrograman yang memayunginya. Secara sederhana, paradigma pemrograman adalah cara pandang atau cara berpikir seseorang mengenai pemrograman dari sudut pandang tertentu. Beberapa paradigma pemrograman yang dikenal luas adalah: •
•
•
Pemrograman Imperatif (Imperative Programming). Dalam paradigma ini, program merupakan susunan dari rangkaian perintah yang rinci (detail commands/ instructions) untuk melaksanakan komputasi atas masukan (input) yang diberikan, diikuti dengan menghasilkan keluaran (output) yang diharapkan. Seorang pemrogram komputer yang bekerja menggunakan bahasa pemrograman imperatif "harus" menuliskan perintah secara rinci untuk mendapatkan hasil yang diinginkan. Dalam hal ini pemrogram menangani aspek "How To Do" untuk mencapai solusi persoalan. Contoh bahasa pemrograman imperatif, yaitu Pascal dan C 2 . Pemrograman Fungsional (Functional Programming). Menurut paradigma pemrograman ini, program terdiri dari sekumpulan fungsi yang disusun atau didefinisikan untuk menyelesaikan persoalan tertentu dengan kemampuan menerima masukan dan memberikan keluaran. Contoh bahasa pemrograman fungsional, yaitu ML, LISP, Haskell, Miranda dan Scheme2'4. Pemrograman Logika (Logic Programming). Menurut paradigma pemrograman logika yang dikenal juga sebagai pemrograman deklaratif, program terdiri dari pemyataan logika yang disusun dalam hubungan logika tertentu. Proses komputasi merupakan suatu proses untuk membuktikan apakah pernyataan logika tertentu benar dan proses untuk memperoleh kesimpulan baru
58 Jurnal llmiah llmu Komputer, Vol. 1 No. 1 Januari 2003: 55-64
«
berdasarkan pernyataan-pernyataan dan aturan logika yang sudah ada sebelumnya. Jadi, proses komputasi dilakukan melalui penalaran logika (logical reasoning). Dalam hal ini pemrogram cukup berurusan dengan aspek "What To Do" suatu persoalan. Contoh bahasa pemrograman logika (deklaratif), yaitu Prolog dan Eclipse2,s'6. Pemrograman Berorientasi Objek (Object-Oriented Programming). Dalam kenyataannya, banyak pihak yang tidak sepaham atas pengertian paradigma berorientasi objek . Berdasarkan pengertian murni dari paradigma ini, struktur program terdiri dari sekumpulan objek saling terpisah yang dapat berinteraksi. Mekanisme interaksi antar objek ini berlangsung melalui pertukaran pesan (message exchange). Pada umumnya, setiap objek memiliki satu atau lebih metode/operasi yang teramati sebagai kelakuan (behaviour) suatu objek dan sehimpunan atribut/data yang menjadi sifat (property) objek tersebut. Lebih jauh, kelakuan program tersebut ditandai dengan aktivitas objek-objek yang saling berkirim pesan, di mana objek penerima pesan merespon pesan dengan mengubah keadaan (state) dirinya. Contoh: sebuah objek Titikl diciptakan dari sebuah kelas bernama Titik dengan dua buah atribut, yaitu posisi-x dan posisiy, serta sebuah metode yang bernama Geser yang berfungsi menggeser Titik ke lokasi baru. Dalam paradigma berorientasi objek dikenal beberapa istilah yang lazim disebut, seperti Class, Inheritance, Encapsulation dan Polymorphism. Contoh bahasa pemrograman berorientasi objek, di antaranya: C++ (bahasa hibrid imperatif/ berorientasi objek), Visual Basic.NET (versi terbaru Visual Basic yang mendeklarasikan dirinya sebagai bahasa yang benar-benar (true, pure) berorientasi objek) dan Smalltalk.
3. Contoh pengkodean untuk menyelesaikan persoalan yang sama dalam beberapa bahasa pemrograman yang berbeda Pada bagian ini disajikan sebuah contoh mengenai kecenderungan pentranslasian ide runutan penyelesaian persoalan dalam paradigma imperatif/prosedural menggunakan beberapa bahasa pemrograman yang berbeda. Kasus contoh yang dipilih adalah persoalan pencarian akar persamaan kuadrat. Bahasa pemrograman yang digunakan untuk keperluan ini adalah C (bahasa pemrograman imperatif); C++ dan Java (bahasa pemrograman berorientasi objek); Haskell (bahasa pemrograman fungsional) dan Eclipse (bahasa pemrograman logika). •
Penyelesaian menggunakan bahasa pemrograman imperatif (C).
#include <stdio.h> #include <math.h> int main(void) { float a,b,c ; /* koefisien persamaan */ float d /* diskriminan*/ float x1 ,x2; I* akar-akar persamaan */ float n; /* peubah temporer */ Aspek Imperatif... (Aditya Rama Mitra dan Arnold Aribowo)
59
/* menangkap masukan dari penguna */ printffNilai a : " ) ; scanf("%f", &a); printffNilai b:"); scanf("%f, &b); printffNilai c : " ) ; scanff%f, &c); if (a == 0) || ({a == 0) && (b == 0)) printffBukan Persamaan Kuadrat"); else { d = b*b - 4*a*c; if (d > 0) I* akar-akar real */ { x1 = (-b + sqrt(d))/(2*a); x2 = (-b - sqrt(d))/(2*a); printffxl =%f\n",x1); printff x2 = %f", x2); } else if (d < 0) /* akar-akar imajiner */ { x1 = (-b)/(2*a); n = sqrt(-d) / (2*a); printffxl = %f %s %f%s\n", x 1 , " + ", n, T ) ; printffx2 = %f %s %f%s", x 1 , " -", n, "i"); } else /* akar kembar */ { x1 = (-b)/(2*a); printffxl =x2 = %f, x1); } } return 0; }
•
Penyelesaian menggunakan bahasa pemrograman berorientasi objek (C++).
#include
// Rutin input/output #include // Format nilai floating point #include <math.h> // Fungsi matematika int main() { float a,b,c,x1 ,x2,n; // deklarasi variable float d; // diskriminan cout.setf(ios::fixed, ios::floatfield); //Format data floating point cout.setf(ios::showpoint); cout«setw(6)«setprecision(2); // Lebar field dan letak desimal // Menangkap masukan dari pengguna c o u t « " Nilai a :"; c i n » a ; // Baca koefisien a c o u t « " Nilai b :"; 60 Jurnal llmiah llmu Komputer, Vol. 1 No. 1 Januari 2003: 55-64
c i n » b ; // Baca koefisien b c o u t « " Nilai c:"; cin»c; // Baca koefisien c if (a == 0) || ((a == 0) && (b == 0)) cout«"Bukan Persamaan Kuadrat"; else { d = b*b - 4*a*c; if (d > 0) // akar-akar real { x1 = (-b + sqrt(d))/(2*a); x2 = (-b - sqrt(d))/(2*a); cout«"X1 = " « x 1 « e n d l ; cout«"X2 = " « x 2 « e n d l ; } else if (d < 0) // akar-akar imajiner { x1 = (-b)/(2*a); n = sqrt(-d) / (2*a); cout«"X1 = " « x 1 « " + " « n « " i " « e n d l ; cout«"X2 = " « x 1 « " - " « n « " i " « e n d l ; } else // akar kembar { x1 = (-b)/(2*a); cout«"X1 = X2 = " « x 1 « e n d l ; } } return 0; }// end main
•
Penyelesaian menggunakan bahasa pemrograman berorientasi objek (Java)
import java.io.*; public class FindRoots { public static void main (StringQ args) throws lOException { double a,b,c; // koefisien persamaan double x1=0.0, x2 = 0.0; // akar-akar real dari persamaan double d; // diskriminan ConsoleReader console = new ConsoleReader(System.in); // Menangkap masukan dari pengguna System.out.println ("Nilai a"); a = console.readDoubleQ; // Baca koefisien a System.out.println ("Nilai b"); b = console.readDouble(); // Baca koefisien b System.out.println ("Nilai c"); c = console.readDoubleQ; // Baca koefisien c if (a == 0) || ((a == 0) && (b == 0)) Aspek Imperatif... (Aditya Rama Mitra dan Arnold Aribowo)
61
System.out.printlnfBukan persamaan Kuadrat"); else if (d > 0.0) // akar-akar real { d = b*b - 4*a*c; x1 = (-b + Math.sqrt(d)) / (2*a); x2 = (-b - Math.sqrt(d)) / (2*a); System.out.println("X1 =" + x1); System.out.println("X2 =" + x2); } else if (d < 0) // akar-akar imajiner
I x1 = (-b)/(2*a); n = sqrt(-d) / (2*a); System.out.println("X1 = " + x1 + "+ " + n + T ) ; System.out.println("X2 = " + x1 + "-" + n + T ) ; } else // akar kembar { x1 = (-b)/(2*a); System.out.println("X1 = X2 = " + x1); } } } •
Penyelesaian menggunakan bahasa pemrograman logika (Eclipse). cari_akar(A, B, C, T ) : - D is (B A 2 - 4*A*C), hasil(A,B.D,T).
/* bukan persamaan kuadrat V hasil(0 T) :join_string(["Bukan persamaan kuadrat"],"", T),!. hasil(0,0, _, T) :join_string(["Bukan persamaan kuadrat"],"", T),!. /* akar-akar imajiner */ hasil(A,B,D,T)> D < 0, X is (-B)/(2*A), F is (-D)A0.5/2*A, join_string([X,"+", F, V ] , " " , P), join_string([X,"-", F, "i"],"", W), join_string(["X1 = ", P, "dan X2 = ", W ] , " " , T),!. /* akar kembar */ hasil(A,B,D,T):- D =:= 0, X is (-B)/(2*A), join_string(["X1 = X2 =", X],"", T),!. /* akar-akar real */ hasil(A,B,D,T)> X1 is (-B+DA0.5)/(2*A), X2 is (-B - DA0.5)/(2*A), join_string(rX1 = ", X1, "dan X2 = ", X2],"", T). •
Penyelesaian menggunakan bahasa pemrograman fungsional (Haskell).
- diskriminan -diskriminan :: Float -> Float -> Float -> Float diskriminan a b c = bA2 - 4*a*c 62 Jurnal llmiah llmu Komputer, Vol. 1 No. 1 Januari 2003: 55-64
- akar kembar akarKembar:: Float -> Float -> Float -> Float akarKembar a b c = (-b)/(2.0*a) - akar-akar real akarReal:: Float -> Float -> Float -> (Float, Float) akarReal a b c = (p+w, p-w) where p = (-b)/(2.0*a) w = sqrt (diskriminan a b c)/(2.0*a) - akar-akar imajiner akarlmajiner:: Float -> Float -> Float -> (Float, Float) akarlmajiner a b c = (P.w) where p = (-b)/(2*a) w= sqrt(-(diskriminan a b c))/(2.0*a) - bagian utama cariAkar:: Float ->Float->Float-> String cariAkar a b c |a == 0 || (a == 0 && b == 0) = "Bukan Persamaan Kuadrat" | (diskriminan a b c) > 0 = "X1 ="++showf++",X2 = " ++ show g | (diskriminan a b c) == 0 = "X1 = X2 = " ++ show (akarKembar a b c) | (diskriminan a b c) < 0 = "X1 = " ++ show h ++ " +" ++ show j ++ "i dan X2 =" ++ show h ++" - " ++ show j ++ T where (f,g) • akarReal a b c (h,j) = akarlmajiner a b c Persoalan pencarian akar persamaan kuadrat jelas berada dalam ranah matematika. Dari kelima pengimplementasian persoalan diberikan, secara alami dapat dikatakan bahwa bahasa fungsional merupakan pilihan kakas yang tepat untuk penyelesaian persoalan. Persoalannya menjadi jelas bahwa yang dibutuhkan adalah pendefinisian sebuah fungsi yang akan memberi keluaran berupa akar-akar sebuah persamaan kuadrat. Persamaan kuadrat ini cukup disajikan dalam bentuk representasinya menggunakan ketiga buah koefisien dari persamaan diberikan. Dalam implementasi di atas, ketiga koefisien dimaksud dituliskan sebagai a, b dan c atau A, B dan C. Dalam eksekusi kelima kode yang dibangun, C dan C++ keduanya, seperti juga halnya kode-kode yang lain, memberikan hasil seperti yang diharapkan, kecuali cara penampilan keluaran tampak berbeda. Sekalipun demikian, dengan melakukan translasi, baik disadari atau tidak, pada saat penulisan kode (code generating) dalam C++, aspek imperatif dalam kode C++ karenanya menjadi sangat menonjol. Dalam hal ini, kami menilai bukanlah hal yang mudah untuk memikirkan kelas objek Aspek Imperatif... (Aditya Rama Mitra dan Arnold Aribowo)
63
yang tepat untuk persoalan akar persamaan kuadrat ini. Tetapi, bila permasaiahan besarnya, misalkan, dalam konteks kelas objek matematika dengan fungsi pencari akar kuadrat sebagai salah satu metode yang dicakup, maka persoalannya menjadi bernuansa berorientasi objek.
4. Kesimpulan 1. Menyelesaikan persoalan dengan bahasa pemrograman sesungguhnya berbeda dengan runutan mengenali ranah persoalan diberikan, diikuti kemudian dengan penentuan paradigma pemrograman dan pemilihan bahasa pemrograman. Bahasa pemrograman yang dipilih tentunya merupakan konsekuensi logik dari hasil pengenalan ranah persoalan dan penentuan paradigma pemrograman tertentu yang akan memayungi cara pandang seorang pemrogram (sebagai problem solver). Lebih jauh, dalam persoalan pemilihan bahasa pemrograman ini, pemrogram mempunyai kebebasan untuk menentukan satu atau lebih bahasa pemrograman yang ia akan gunakan sesuai dengan kebutuhannya. 2. Pemahaman berbagai paradigma pemrograman yang ada akan menolong seorang pemrogram memiliki wawasan yang lebih luas, disamping memberi dasar dalam menentukan paradigma pemrograman yang sesuai untuk menyelesaikan persoalan yang diberikan. Analoginya adalah seperti "menentukan jenis pakaian yang tepat untuk situasi tertentu." 3. Kemampuan untuk menerapkan paradigma yang berbeda (paradigm change) membantu seorang pemrogram dalam membangun sebuah program di mana gaya pemrogramannya akan tampak sejalan dengan paradigma yang memayunginya. Dalam terminologi produk, hal ini diekspresikan sebagai isi yang sesuai dengan kemasannya (content versus container), yang pada saat sama mengandung pengertian bahwa isi seharusnya mendapat perhatian yang setidaknya berimbang dengan atau lebih banyak ketimbang kemasannya.
Daftar Pustaka 1
2
3
4
s 6
MacLennan, Bruce, "Principles of Programming Languages", Holt-Saunders, 1987. Sethi, Ravi., "Programming Languages: Concept & Constructs", ed. 2, AT&T Bell Laboratories, 1996. Stroustrup, B., "What is "Object-Oriented Programming"? (1991 revised version)", AT&T Bell Laboratories, 1991. Thompson, Simon, "Haskell The Craft of Functional Programming", Addison Wesley, 1996. http://www.icparc.ic.ac.uk/eclipse/ http://www.pdc.dk/vipdownload/doc/lanauaqe.zip
64 Jurnal llmiah llmu Komputer, Vol. 1 No. 1 Januari 2003: 55-64