haskel

download haskel

of 33

Transcript of haskel

Haskell Programming Languages

MAKALAH

BAHASA PEMROGRAMAN HASKELL

Penyusun: Anjar Priandoyo Luqman Rakhman Sapta Ferdinansyah Hayuning Titi K. Y.B. Dafferianto T. Anshari Agro Rachmatullah

(08200) (08960) (09010) (09074) (09099) (09102) (09374)

Dosen Pengajar: Agus Sihabudin, S.Si.

PROGRAM STUDI ILMU KOMPUTER FAKULTAS MATEMATIKA DAN ILMU PENGETAHUAN ALAM UNIVERSITAS GADJAH MADA 2004

Konsep Bahasa Pemrograman

1

Haskell Programming Languages

KATA PENGANTARPertama-tama kami mengucapkan syukur kepada Tuhan Yang Maha Esa, karena berkatNya lah akhirnya kami satu tim dapat menyelesaikan makalah mengenai bahasa pemrograman Haskell ini. Adapun pembuatan makalah ini ditujukan untuk penyelesaian tugas untuk mata kuliah Konsep Bahasa Pemrograman program studi Ilmu Komputer FMIPA UGM, selain juga sebagai pengantar kepada pembaca untuk lebih mengerti bahasa Haskell sebagai bahasa fungsional, juga untuk menambah khasanah keilmuan tentang bahasa pemrograman yang ada terlebih yang sangat berminat pada bidang pemrograman. Bahasa pemrograman merupakan implementasi dari algoritma yang dibuat oleh pemrogram dalam memberikan perintah kepada komputer untuk menyelesaikan masalah tertentu. Sampai saat ini banyak bahasa program yang dikembangkan seiring dengan kebutuhan akan kemudahan dalam pemrograman. Bahasa pemrograman dikategorikan dalam beberapa kategori berdasarkan kedekatannya dengan bahasa manusia, yaitu bahasa tingkat tinggi (high level language), bahasa tingkat menengah (middle level language), dan bahasa tingkat rendah (low level language). Semakin tinggi tingkatan sebuah bahasa, semakin dekat dengan basaha manusia (dalam hal ini bahasa Inggris). Dari sudut pandang yang berbeda, bahasa pemrograman dikategorikan menjadi bahasa deklaratif, bahasa imperatif, dan bahasa fungsional. Bahasa prosedural dan object-oriented termasuk bahasa imperatif. Haskell merupakan salah satu contoh bahasa pemrograman fungsional. Berbeda dengan bahasa pemrograman terstruktur, bahasa fungsional tidak dieksekusi berdasarkan urutan perintah-perintah, tetapi dengan mengevaluasi ekspresi-ekspresi. Mungkin, Haskell kurang begitu familiar di kalangan mahasiswa, maka dari itu dalam makalah ini kami akan menjabarkan bahasa Haskell secara umum bersama contohcontoh sintaksnya dengan harapan dapat mengenalkan bahasa pemrograman ini. Akhirnya tak ada gading yang tak retak, makalah ini masih penuh kekurangan dan kesalahan maka kami berharap para pembaca dapan memberikan saran dan petunjuk agar mskslsh ini menjadi lebih berisi, semoga makalah ini dapat bermanfaat dan berkenan di hati para pembaca.

Yogyakarta, 2 April 2004 Penyusun

Konsep Bahasa Pemrograman

2

Haskell Programming Languages

DAFTAR ISIKATA PENGANTAR DAFTAR ISI 2 3

BAB I PENDAHULUANI.1 What is Haskell?Haskell merupakan bahasa pemrograman yang fungsional, malas dan murni. Ia disebut malas karena tidak mengevaluasi ekspresi-ekspresi yang digunakannya yang sebenarnya memang tidak diperlukan untuk menentukan jawaban bagi suatu masalah. Kebalikan dari malas adalah teliti yang merupakan strategi pengevaluasian bagi kebanyakan bahasa pemrograman (C, C++, Java, bahkan ML). Salah satu ciri dari bahasa yang teliti adalah setiap ekspresi diteliti apakah hasil dari perhitungan tersebut penting atau tidak.(Hal ini mungkin tidak mutlak benar seluruhnya karena adanya pengoptimalan compiler yang sering disebut denganeleminasi kode matiyang akan menghilangkan ekspresi yang tidak digunakan di program yang sering dilakukan oleh bahasa-bahasa tersebut). Haskell disebut murni karena bahasa ini tidak memperbolehkan adanya efek samping (Efek samping adalah sesuatu yang mempengaruhi bagian di program. Misalnya suatu fungsi yang mencetak sesuatu ke layar yang mempengaruhi nilai dari variabel global. Tentu saja, suatu bahasa pemrograman yang tanpa efek samping akan menjadi sangat tidak berguna; Haskell menggunakan sebuah system monads untuk mengisolasi semua komputasi kotor dari program dan menampilkannya dengan cara yang aman. Haskell disebut bahasa fungsional karena evaluasi dari programnya sama dengan mengevaluasi sebuah fungsi dalam bahasa matematika murni. Hal ini juga yang membedakannya dari bahasa standard (seperti C dan Java) yang mengevaluasi sederetan pernyataan secara urut (inilah pola dari bahasa terstruktur ) Yang termasuk dalam bahasa pemrograman fungsional antara lain Lisp, Scheme, Erlang, Clean, Mercury, ML, OCaml, SQL, XSL dan lain-lain. Di antara bahasa fungsional tersebut, Haskell merupakan bahasa yang ideal dalam banyak hal. Bahasa fungsional seperti juga bahasa logika seperti Prolog adalah deklaratif. Kebalikannya yaitu bahasa procedural dan bahasa yang berorientasi pada obyek adalah terstruktur. Haskell memiliki sintak yang lebih mudah untuk dipahami

Konsep Bahasa Pemrograman

3

Haskell Programming Languages

daripada Lisp--bahasa turunan--(terutama bagi pemrogram yang pernah menggunakan bahasa yang menggunakan tanda baca yang sederhana/ringan seperti Python, TCL and REXX). Kebanyakan operatornya bersifat infix, tapi ada juga yang prefix. Pengaturan indentasi dan modulnya sangatlah familiar dan mungkin sangat menarik, misalnya tanda kurung bersarang yang terlalu dalam (seperti yang terlihat dalam Lisp) dihindari.

I.2 The History of HaskellPada bulan September tahun 1987 diadakan pertemuan dalam konferensi Bahasa Pemrograman Fungsional dan Arsitektur Komputer atau Functional Programming Languages and Computer Architecture (FPCA 87) di Portland, Oregon, untuk membicarakan keadaan yang kurang menguntungkan di komunitas pemrograman fungsional yaitu adanya selusin bahasa pemrograman fungsional yang murni, kesemuanya mirip dalam hal bentuk ekspresi dan sintaknya. Telah dihasilkan suatu konsensus yang kuat dalam pertemuan itu yaitu bahwa penyebarluasan kegunaan dari kelas bahasa fungsional ini telah dihalangi oleh kekurangan dari kebanyakan bahasa. Telah diputuskan juga bahwa harus ada sebuah komite yang dibentuk untuk merancang suatu bahasa yang menyediakan komunikasi gagasan baru yang lebih cepat, suatu dasar yang stabil bagi pengembangan aplikasi nyata dan sebuah cara untuk membuat orang tertarik menggunakan bahasa fungsional. Kemudian diciptakanlah sebuah bahasa pemrograman fungsional yang murni yang dinamai Haskell. Nama tersebut diambil dari nama seorang ahli logika yaitu Haskell B. Curry yang telah menciptakan banyak dasardasar logika bagi kita. Tujuan utama dari komite tersebut adalah untuk merancang bahasa yang memenuhi syarat sebagai berikut : 1. Harus cocok untuk pengajaran, penelitian dan aplikasi termasuk untuk membuat sistem yang besar. 2. Harus seluruhnya dijelaskan melalui sintak dan semantik yang formal. 3. Harus tersedia secara bebas. Semua orang boleh mengimplementasikan bahasa tersebut dan menyebarkannya ke siapa saja yang mereka sukai. 4. Harus didasarkan pada gagasan yang sesuai dengan konsensus umum. 5. Harus mengurangi perubahan yang tidak diperlukan dalam bahasa pemrograman fungsional. Komite tersebut menganggap bahwa Haskell dapat dijadikan sebagai bahan penelitian masa depan dalam bidang rancangan bahasa dan berharap bahwa variasi bahasa akan muncul sesuai dengan hasil percobaan. Haskell kemudian terus berkembang sejak dipublikasikan. Pada pertengahan tahun 1997, telah ada empat rancangan bahasa yang dihasilkan (yang terbaru pada saat itu adalah Haskell 1.4). Pada saat workshop Haskell tahun 1997 di Amsterdam, diputuskan bahwa diperlukan varian yang stabil dari Haskell. Bahasa yang stabil ini disebut Haskell 98. Haskell 98 mirip dengan Haskell 1.4, tapi iaKonsep Bahasa Pemrograman

4

Haskell Programming Languages

menawarkan beberapa penyederhanaan dan penghilangan lubang-lubang jebakan karena ketidakhati-hatian. Setelah Haskell 98 stabil, kelihatan jelas sekali bahwa banyak program memerlukan akses ke suatu set pustaka fungsi yang lebih banyak (yakni berhubungan dengan input/output dan interaksi ringan dengan sistem operasi). Jika program ini menjadi fleksibel, sekumpulan pustaka harus distandarkan juga. Sejumlah usaha dilakukan oleh komite untuk memperbaiki pustaka Haskell 98.

BAB II HASKELL, FULLY FUNCTIONAL PROGRAMMING LANGUAGEII.2 Haskell sebagai Bahasa Pemrograman Fungsional (Functional Programming Language)Haskell merupakan salah satu dari banyak bahasa pemrograman fungsional, seperti Lisp, Scheme, Erlang, Clean, Mercury, ML, Ocaml, SQL, XSL, dll. Mirip dengan bahasa pemrograman fungsional, bahasa pemrograman logical seperti Prolog merupakan bahasa pemrograman deklaratif. Berlawanan dengan kedua kategori di atas, bahasa pemrograman prosedural dan object-oriented masuk dalam kategori bahasa pemrograman terstruktur. Dikatakan terstruktur, karena mengandung urutan perintah yang dieksekusi satu demi satu secara strict (keras). Beberapa bahasa pemrograman seperti Python, Perl, dan Ruby melewati batasan-batasan paradigma di atas. Di antara bahasa pemrograman fungsional, Haskell dalam banyak hal merupakan yang paling ideal. Haskell merupakan bahasa pemrograman fungsional murni, yang berarti jauh dari efek samping. Bahasa pemrograman fungsional merupakan ekspresi tunggal, yang dieksekusi dengan mengevaluasi ekspresi tersebut. Bahasa pemrograman fungsional mirip dengan spreadsheet, di mana nilai dari tiap cell ditetapkan yang berpengaruh pada nilai dari cell lainnya. Fokusnya adalah pada apa yang akan dihitung, bukan bagaimana proses penghitungannya. Adapun kelebihan dari bahasa pemrograman fungsional antara lain: 1. Singkat. Program fungsional cenderung lebih ringkas dibanding program terstruktur (2 sampai 10 kali). 2. Mudah dimengerti.

Konsep Bahasa Pemrograman

5

Haskell Programming Languages

Program fungsional seringjali lebih mudah untuk dimengerti. Dalam kasus Quicksort, tidak terlalu diperlukan pengetahuan mengenai Haskell maupun quicksort. Hal tersebut tidak dapat terjadi pada program C, yang membutuhkan waktu untuk dimengerti, dan sangat mudah untuk melakukan kesalahn kecil yang mengakibatkan program tidak dapat dieksekusi. 3. Tidak ada tumpukan pada memori. Tidak ada kemungkinan memperlakukan integer sebagai pointer, atau dilanjutkan dengan pointer null.

4. Kode dapat digunakan kembali. Bahasa pemrograman fungsional menggunakan polymorphism, yang akan meningkatkan penggunaan kembali kode. 5. Pelekatan yang kuat. Bahasa fungsional non-strict memliki fitur kuat lainnya: hanya mengevaluasi program seperti yang diperlukan untuk menghasilkan jawaban, yang sering disebut dengan lazy evaluation. Struktur data dievaluasi secukupnya untuk menghasilkan jawaban, dan sebagian mungkin tidak dievaluasi sama sekali. Hal ini memungkinkan pelekatan untuk menyusun bersama program yang sudah ada. Hal ini memungkinkan penggunaan kembali program, atau potongan program lebih sering dari yang dapat dilakukan oleh pengaturan terstruktur. 6. Abstraksi yang kuat. Secara umum bahasa fungsional menawarkan cara-cara baru yang kuat untuk meng-enkapsulasi abstraksi. Abstraksi mengizinkan kita untuk menentukan objek yang pekerjaan internalnya tersembunyi. Abstraksi merupakan kunci untuk membangun program modular yang dapat dipelihara. Satu mekanisme abstraksi yang kuat yang terdapat dalam bahasa fungsional adalah higher-order function. 7. Manajemen memori yang terintegrasi. Kebanyakan program rumit perlu mengalokasikan memori dinamis dari tumpukan (heap). Setiap bahasa fungsional memudahkan pemrogram dari beban manajemen penyimpanan tersebut. Penyimpanan dialokasikan dan diinisialisaikan secara implisit, dan diselamatkan secara otomatis oleh kolektor sampah.

II.2 Why Use Haskell?Menulis system software yang besar sangatlah sulit dan mahal. Dan bahkan untuk mengelola system itu bisa lebih sulit dan lebih mahal. Bahasa pemrograman fungsional semacam Haskell dapat membuatnya lebih mudah dan lebih murah. Haskell sebagai bahasa pemrograman fungsional murni dapat :Konsep Bahasa Pemrograman

6

Haskell Programming Languages

1. Meningkatkan produktifitas programmer (Ericsson banyak memanfaatkan hasil percobaan Haskell dalam software telephony) 2. Lebih singkat, lebih jelas dan kode-kodenya mudah dibaca 3. Errornya semakin sedikit dan reabilitynya lebih tinggi 4. Membuat jarak antara programmer dengan bahasa itu lebih pendek 5. Waktu untuk membuat program menjadi lebih singkat Banyak alasan untuk menggunakan Haskell diantaranya adalah kita bisa menulis kode bebas atau bugs-free code dalam waktu yang lebih singkat dibanding bahasa lainnya. Bahasa ini terus-menerus berkembang dan kian hari makin banyak kelebihannya. Selain itu, Haskell cocok untuk berbagai macam aplikasi. Sebagai contoh: Quicksort dalam Haskell:qsort[] = [] qsort(x:xs)= qsort elts_lt_x ++ [x] ++ qsort elts_lt_greq_x where elts_lt_x = [y|y mkAdder n = addN where addN m = n+m > add7 = mkAdder 7

Konsep Bahasa Pemrograman

10

Haskell Programming Languages

Operator dan Fungsi Precedence (fungsi yang didahulukan) Operator di dalam Haskell dibagi dalam berbagai tingkatan yang lebih tinggi. Kebanyakan hal ini sama halnya dengan apa yang kamu harapkan dari bahasa pemrograman yang lain. Perkalian harus didahulukan penambahan, dan seterusnya (maka " 2*3+4" adalah 10, bukan 14). Di dalam Haskell sebuah precedence (fungsi atau nama yang didahulukan) adalah mudah untuk melakukan kesalahan. Fungsi harus didahulukan daripada operator. Hasil daripada pernyataan tersebut adalah untuk ekspresi " f g 5" artinya " apply g ( dan 5) sebagai argumen ke f "bukan" apply hasil dari (g 5) ke f". Kesalahan semacam ini akan menghasilkan suatu pemberitahuan kesalahan oleh compiler, karena, sebagai contoh, f akan memerlukan suatu Integer sebagai suatu argumen bukannya memerlukan fungsi yang lain. Sebagai contoh kesalahan yang lebih fatal adalah kita bisa membikin suatu argument yang valid tetapi salah, adalah :double res1 = res2 = res3 = res4 = res4 = n = n*2 double 5^2 -- 'res1' is 100, i.e. (5*2)^2 double (5^2) -- 'res2' is 50, i.e. (5^2)*2 double double 5 -- Causes a compile-time error double (double 5) -- 'res4 is 20, i.e. (5*2)*2 double (double 5) -- 'res4 is 20, i.e. (5*2)*2

Sama Seperti bahasa pemrograman yang lainnya, tanda kurung sangat bermanfaat di dalam ekspresi-ekspresi yang bisa bermakna ambigu, di mana kamu ragu tentang mana yang didahulukan (precedence). Tanda kurung tersebut tidak digunakan pada argumen fungsi di dalam Haskell, tetapi tidak juga salah bila ada, yang mana hanya akan menciptakan tambahan penggolongan ekspresi baru ( seperti pada contoh res2 di atas).

III.3 Lingkup Nama (Scope of names)Pada awalnya mungkin terlihat bahwa ada suatu hal yang saling berlawanan antara dua poin pada ekspresi-ekspresi dalam Haskell. Pada satu kasus dijelaskan bahwa variable nama yang didefinisikan sebagai ekspresi hanya boleh sekali dalam program, tetapi pada sisi lain, banyak dari contoh menggunakan variabel yang sama berulang-kali. Kedua-Duanya benar, tetapi perlu untuk dicermati, tiap-tiap nama didefinisikan persisnya hanya sekali di dalam lingkup (Scope) yang ditentukan. Tiap-tiap definisi fungsi menggambarkan scope atau lingkupnya sendiri dan beberapa dibangun dengan scope yang lebih local. Suatu variable (suatu nama) hanya dapat terjadi sekali sesuai dengan blok indentasinya. Sebagai contoh :x x y -- 'x' as arg is in different scope than func name | y==1 = y*x*z -- 'y' from arg scope, but 'x' from 'where' scope | otherwise = x*x -- 'x' comes from 'where' scope

Konsep Bahasa Pemrograman

11

Haskell Programming Languages

where x = 12 -- define 'x' within the guards z = 5 -- define 'z' within the guards n1 = x 1 2 -- 'n1' is 144 ('x' is the function name) n2 = x 33 1 -- 'n2' is 60 ('x' is the function name)

Argumen hanya mempunyai suatu scope atau lingkup di dalam definisi fungsi tertentu dan nama yang sama dapat digunakan di dalam definisi fungsi yang lain. Bagian yang dapat dicatat dari bahasa pemrograman Haskell ini adalah definisi fungsi tersebut di dalam Haskell akan menjadi fungsi yang lebih singkat dibanding bahasa pemrograman yang lain. Ini merupakan sebagian dari kaitan dengan sintaks Haskell yang ringkas, tetapi suatu alasan lebih kuat adalah karena penekanan di dalam fungsional programming adalah memerinci permasalahan ke dalam bagian komponen mereka ( dibanding hanya, "membuat apa yang perlu untuk dilaksanakan" pada masingmasing poin di dalam suatu pemrograman terstruktur ). Ini mendorong reusabilitas (penggunaan kembali) komponen, dan mengijinkan banyak verifikasi lebih baik yang mana masing-masing bagian benar-benar mengerjakan apa yang seharusnya dilakukan.. Bagian kecil dari definisi fungsi dapat dijelaskan dengan beberapa cara. Pertama adalah untuk menggambarkan banyak pendukungan terhadap fungsi di dalam suatu source-file, dan menggunakannya jika dibutuhkan. Bagaimanapun, ada dua cara yang ekivalen untuk mendefinisikan pendukungan Fungsi di dalam lingkup dari suatu definisi fungsi yang tunggal, yaitu the let Clause dan the where clause. salah satu contoh sederhan dari penjelasan diatas :f n = n+n*n f2 n = let sq = n*n in n+sq f3 n = n+sq where sq = n*n where sq = n*n

Ketiga definisi diatas adalah ekivalen, tetapi f2 dan f3 memilih untuk menggambarkan fungsi sq di dalam lingkup definisi.

III.4 Importing/exportingHaskell juga mendukung suatu sistem modul yang mempertimbangkan skala modularitas fungsi yang lebih besar. Dua elemen dasar dari modul control adalah spesifikasi import dan export suatu variable. Sebagai contoh :-- declare the current module, and export only the objects listed module MyNumeric ( isPrime, factorial, primes, sumSquares ) where import MyStrings -- import everything MyStrings has to offer

Konsep Bahasa Pemrograman

12

Haskell Programming Languages

-- import only listed functions from MyLists import MyLists ( quicksort, findMax, satisfice ) -- import everything in MyTrees EXCEPT normalize import MyTrees hiding ( normalize ) -- import MyTuples as qualified names, e.g. -- three = MyTuples.third (1,2,3,4,5,6) import qualified MyTuples

BAB IV NILAI, TIPE, DAN ATRIBUT LAINNYAIV.1 Tipe DataSebelumnya akan dibahas dulu tipe-tipe data yang akan digunakan, yaitu Integer, Char, dan Double, Bool, dan list. Integer menyatakan bilangan bulat. Contoh Integer adalah -1, 0, dan 20. Char menyatakan karakter (simbol-simbol yang digunakan untuk penulisan), yang contohnya adalah a, ?, dan 4. Double menyatakan bilangan floating point, yaitu tipe data bilangan yang bisa melambangkan pecahan. Contohnya adalah 3.14, 0.0, dan -1.69. Perhatikan bahwa 0 adalah Integer sedangkan 0.0 merupakan floating point. 2.0, 5.0, dan 11.0 juga merupakan floating point. Tipe data Integer tidak akan pernah dituliskan menggunakan tanda desimal (titik), sedangkan tipe data floating point selalu dituliskan menggunakan tanda desimal. Bool dapat bernilai True atau False (tidak keduanya). List sendiri secara mudahnya adalah deretan dari data-data yang tipenya sama. Contohnya adalah [1,2,3] yang merupakan list Integer. Karena Haskell merupakan bahasa fungsional murni, semua perhitungan dilakukan melalui evaluasi dari ekspresi (terminologi sintaks) untuk menghasilkan nilainilai (entitas abstrak yang dianggap sebagai jawaban). Setiap nilai berasosiasi dengan satu tipe (secara intuisi tipe dapat dianalogikan sebagai himpunan nilai-nilai). Ekspresi termasuk nilai-nilai atomik seperti integer 5, karakter a, dan fungsi \x -> x+1, seperti halnya juga nilai-nilai terstruktur seperti list [1,2,3] dan pasangan (b,4). Seperti halnya ekspresi menandai nilai, ekspresi tipe merupakan terminologi sintaks yang menandai tipe nilai. Ekspresi tipe termasuk tipe atomik Integer (integer dengan ketepatan tanpa batas), Char (karakter), Integer->Integer (fungsi pemetaan

Konsep Bahasa Pemrograman

13

Haskell Programming Languages

Integer ke Integer), juga tipe terstruktur [Integer] (list integer homogen) dan (Char,Integer) (pasangan integer dan karakter). Semua nilai dalam Haskell adalah first-class- dapat dilewatkan sebagai argumen ke fungsi, dikembalikan sebagai hasil, diletakkan dalam struktur data, dll. Tipe dalam Haskell, pada sisi lain, bukan merupakan first class. Tipe dalam hal mendeskripsikan nilai, dan asosiasi dari nilai dengan tipenya dinamakan typing. Typing dapat ditulis sebagai berikut:5 a inc [1,2,3] (b,4) :: :: :: :: :: Integer Char Integer -> Integer [Integer] (Char,Integer)

:: dibaca bertipe. Fungsi dalam Haskell biasanya digambarkan sebagai rangkaian persamaan. Sebagai contoh fungsi inc dapat digambarkan sebagai persamaan tunggal:inc n = n+1

Sebuah persamaan merupakan contoh dari sebuah deklarasi. Jenis lain dari deklarasi adalah type signature declaration, di mana dapat dideklarasikan typing secara eksplisit untuk inc:inc :: Integer -> Integer

Untuk tujuan pendidikan, jika akan diindikasikan sebuah ekspresi c1 menghasilkan atau menurunkan ekspresi atau nilai c2, maka ditulis:c1

c2

Sebagai contoh:inc(inc 3)

5

Sistem tipe statis pada Haskell menggambarkan hubungan formal antara tipe dan nilai. Sistem tipe statis meyakinkan program Haskell type safe; yaitu pemrogram aman dari kesalahan pemilihan tipe. Sebagai contoh tidak dapat dilakukan penjumlahan 2 karakter, sehingga ekspresi a+b merupakan penulisan yang salah. Keuntungan utama dari bahasa bertipe statis adalah semua kesalahan/error tipe terdeteksi saat program dicompile. Tidak semua kesalahan ditangkap oleh sistem tipe; ekspresi seperti 1/0 dapat bertipe, tetapi akan menghasilkan kesalahan pada waktu eksekusi. Tetapi sistem tipe

Konsep Bahasa Pemrograman

14

Haskell Programming Languages

masih menemukan kesalahan program pada waktu compile, yang mengizinkan compiler untuk menghasilkan kode yang lebih efisien. Sistem tipe juga memastikan bahwa user-supplied type signature adalah benar. Dalam kenyataannya sistem tipe pada Haskell cukup kuat untuk mengizinkan pengguna untuk menghindari menulis type signature sama sekali; dengan kata lain sistem tipe menyimpulkan tipe yang benar untuk pengguna.

IV.2 Tipe PolimorfisHaskell juga menyertakan tipe polimorfis tipe yang dalam beberapa cara terukur di atas semua tipe. Ekspresi tipe polimorfis menguraikan keluarga dari tipe-tipe. Sebagaia contoh, ( )[a] adalah keluarga dari tipe di mana untuk setiap tipe a berisi tipe list dari

a. List dari integer (seperti [1,2,3]), list dari karakter ([a,b,c]), sekalipun list dari list integer, dll, adalah anggota dari keluarga ini. (Sebagai catatan [2,b] bukan contoh yang valid karena tidak ada tipe tunggal yang berisi 2 dan b). List merupakan struktur data yang umum digunakan dalam bahasa fungsional, dan merupakan sarana yang baik untuk menerangkan prinsip-prinsip dari polimorfisme. List [1,2,3] dalam Haskell merupakan kependekan dari list 1:(2:(3:[])), di mana [] merupakan list kosong dan : merupakan operator infix yang meletakkan argumen pertama di depan argumen kedua (dalam hal ini list), atau dapat juga ditulis 1:2:3:[]. Sebagai contoh dari fungsi user-defined yang beroperasi pada list, pertimbangkan masalah menghitung jumlah elemen dalam list berikut:length length [] length (x:xs) :: [a] -> Integer = 0 = 1 + length xs

Dari persamaan di atas terbaca: Panjang dari list kosong adalah 0, dan panjang dari list di mana elemen pertamanya x dan sisanya xs adalah 1 ditambah panjang dari xs. (sebagai catatan xs merupakan jamak dari x, dan harus dibaca demikian). Walaupun secara intuitif, contoh di atas menyorot sebuah aspek penting dari Haskell, yaitu pattern matching (pencocokan pola). Ruas kiri persamaan mengandung pola seperti [] dan x:xs. Dalam sebuah fungsi aplikasi, pola-pola seperti ini dibandingkan dengan parameter aktual (nyata) dengan cara intuitif ([] hanya cocok dengan list kosong, dan x:xs akan cocok dengan list apa saja dengan minimal satu elemen, x dihubungkan dengan elemen pertama dan xs dengan sisanya dalam list). Jika pencocokan sukses, ruas kanan dievaluasi dan dikembalikan sebagai hasil dari aplikasi. Jika gagal, persamaan berikutnya akan dicoba, dan jika semua persamaan gagal, maka hasilnya error.

Konsep Bahasa Pemrograman

15

Haskell Programming Languages

Fungsi length di atas juga merupakan contoh dari sebuah fungsi polimorfis. Fungsi tersebut dapat diterapkan pada list yang berisi elemen bertipe apa saja, sebagai contoh [Integer], [Char], atau [[Integer]].length [1,2,3] length [a,b,c] length [[1],[2],[3]]

3 3 3

Berikut adalah 2 contoh fungsi polimorfis dalam list. fungsi head mengembalikan elemen pertama dari list, fungsi tail mengembalikan semua elemen kecuali elemen pertama.head :: [a] -> a head (x:xs) = x tail :: [a] -> [a] tail (x:xs) = xs

Tidak seperti fungsi length, fungsi-fungsi di atas tidak didefinisikan untuk semua nilai yang mungkin dari argumen mereka. Runtime error (kesalahan saat program dijalankan) akan muncul saat fungsi-fungsi tersebut diterapkan pada list kosong. Dengan tipe polimorfis beberapa tipe lebih umum dibanding lainnya dalam hal himpunan nilai yang didefinisikan lebih besar. Sebagai contoh tipe [a] adalah lebih umum dari [Char]. Dengan kata lain, tipe terakhir dapat diturunkan dari sebelumnya dengan substitusi yang cocok untuk a. Dibandingkan dengan bahasa bertipe monomorfis seperti C, polimorfisme meningkatkan ke-ekspresif-an, dan tipe inferensi meringankan beban tipe dari pemrogram. Tipe prinsipal (utama) dari ekspresi atau fungsi adalah tipe yang paling tidak umum, secara intuitif, berisi semua instan dari ekspresi. Sebagai contoh, tipe prinsipal dari fungsi head adalah [a] -> a; [b] -> a, a -> a.

IV.3 Tipe User-DefinedKita dapat menentukan tipe data sendiri dalam Haskell menggunakan deklarasi data. Tipe penting yang sudah dikenal oleh Haskell adalah nilai kebenaran:data Bool = False | True

Tipe yang didefinisikan di sini adalah Bool yang mempunyai dua nilai, yaitu True dan False. Tipe Bool adalah sebuah contoh dari tipe konstruktor, dan True dan False adalah data konstruktor (atau konstruktor saja).

Konsep Bahasa Pemrograman

16

Haskell Programming Languages

Dengan cara yang sama kita dapat mendefinisikan tipe warna:data Color = Red | Green | Blue | Indigo | Violet

Bool dan Color dalam contoh di atas merupakan tipe enumerasi. Berikut contoh dari tipe dengan hanya satu data konstruktor:data Point a = Pt a a

Karena merupakan konstruktor tunggal, tipe seperti Point sering disebut tipe tuple, karena merupakan produk kartesian (dalam hal ini biner) dari tipe lain. Berlawanan dengan itu, tipe multi-konstruktor seperti Bool dan Color disebut union dari tipe sum. Point merupakan contoh dari tipe polimorfis: untuk semua tipe t, ia mendefinisikan tipe dari titik-titik kartesian yang menggunakan t sebagai tipe koordinat. Dalam contoh sebelumnya [] juga merupakan tipe konstruktor. Pada tipe t (bertipe apa saja) dapat diterapkan [] untuk menghasilkan tipe baru [t]. sintaks Haskell mengizinkan [] t ditulis sebagai [t]. -> juga merupakan tipe konstruktor; diberikan 2 tipe t dan u, t -> u merupakan tipe dari fungsi pemetaan elemen dari tipe t ke elemen dari tipe u. Catatlah bahwa tipe dari konstruktor data biner Pt adalah a -> a -> Point a, sehingga yang berikut adalah valid:Pt 2.0 3.0 Pt a b Pt True False :: :: :: Point Float Point Char Point Bool

Pada sisi lain, ekspresi seperti Pt a 1 tidak valid karena a dan 1 berbeda tipe. Penting untuk membedakan antara menerapkan data konstruktor untuk menghasilkan nilai, dan menerapkan tipe konstruktor untuk menghasilkan tipe; yang pertama terjadi saat run-time dan bagaimana kita menghitung dalam Haskell, di mana yang terakhir terjadi saat compile-time. Tipe konstruktor seperti Point dan data konstruktor seperti Pt adalah dalam namespaces terpisah. Ini memungkinkan nama yang sama untuk digunakan oleh tipe konstruktor dan data konstruktor, seperti berikut:data Point a = Point a a

IV.4 Tipe RekursifTipe dapat juga rekursif, seperti tipe dalam pohon biner:

Konsep Bahasa Pemrograman

17

Haskell Programming Languages

data Tree a = Leaf a | Branch (Tree a) (Tree a)

Di sini didefinisikan tipe polimorfis pohon biner yang mana elemen-elemennya adalah node Leaf berisi nilai dari tipe a, atau node internal (branch) berisi dua sub-tree (rekursif). Saat membaca deklarasi data seperti ini, ingat bahwa Tree adalah tipe konstruktor, di mana Branch dan Leaf adalah data konstruktor. Di samping menciptakan koneksi antara konstruktor-konstruktor ini, deklarasi di atas mendefinisikan tipe berikut untuk Branch dan Leaf:Branch Leaf :: :: Tree a -> Tree a -> Tree a a -> Tree a

Dengan contoh di atas telah didefinisikan suatu tipe yang cukup kaya untuk mendefinisikan beberapa fungsi (rekursif) yang menggunakannya. Sebagai contoh akan didefinisikan sebuah fungsi fringe yang mengembalikan sebuah list dari semua elemen dalam daun dari sebuah pohon dari kiri ke kanan. Biasanya akan sangat membantu jika dituliskan terlebih dulu tipe dari fungsi baru; dalam kasus ini tipe seharusnya Tree a -> [a]. fringe merupakan fungsi polimorfis di mana untuk semua tipe a, memetakan pohon dari a ke list dari a. Definisi yang tepat sebagai berikut:fringe :: Tree a -> [a] fringe (Leaf x) = [x] fringe (Branch left right) = fringe left ++ fringe right

Di sini ++ merupakan operator infix yang menggabungkan dua list.

IV.5 Tipe SinonimUntuk kenyamanan, Haskell menyediakan cara untuk mendefinisikan tipe sinonim, yaitu nama untuk tipe yang sering dipakai. Tipe sinonim dibuat menggunakan deklarasi type. Berikut beberapa contoh:type type type data String Person Name Address = [Char] = (Name,Address) String None | Addr String

= =

Tipe sinonim tidak mendefinisikan tipe baru, tetapi memberi nama baru kepada tipe-tipe yang sudah ada. Sebagai contoh tipe Person -> Name setara dengan (String,Address) -> String. Nama yang baru seringkali lebih pendek dari tipe sinonimnya, tetapi itu bukan satu-satunya tujuan dari tipe sinonim: tipe sinonim

Konsep Bahasa Pemrograman

18

Haskell Programming Languages

meningkatkan kemudahan membaca sebuah program dengan menjadi lebih mnemonik. Bahkan tipe polimorfis sekalipun dapat diberi nama baru:type AssocList a b = [(a,b)]

Ini merupakan tipe asosiasi yang mengasosiasikan nilai dari tipe a dengan nilai dari tipe b.

IV.6 OperatorUntuk tipe data angka, terdapat operator aritmatika untuk penjumlahan, pengurangan, perkalian, dan pembagian. Dengan operator-operator tersebut, kita bisa menggunakan interpreter Haskell sebagaimana menggunakan kalkulator. Inilah beberapa contohnya:? 1 + 1 > 2 ? 5 3 > 2 ? 7 * 7 > 49 ? 4 / 2 > 2.0 ? (2 * 2) - (4 * 1 * 3) > -8 ? 3.14 * 2.1 * 2.1 > 13.8474

Dalam contoh-contoh di atas, tanda tanya (?) mengawali input yang kita tuliskan dan tanda lebih besar (>) mengawali outputnya. Salah satu hal yang menarik adalah bahwa pembagian Integer dengan Integer menghasilkan bilangan floating point. Hal ini seperti di Pascal, dan berbeda dengan LISP (nenek moyang Haskell) dan C/C++/C#/Java. Di Haskell, list merupakan tipe data yang fundamental. Seperti yang telah disebutkan, list hanya bisa berisi satu tipe data (misalnya integer). Membuat list sangatlah mudah, yaitu dengan syntax berikut:? [1, 2, 3, 4] > [1,2,3,4] ? [a, b, c] > [1,2,3,4] ? [3.14, 2.72] > [3.14,2.72] ? [] > []

Konsep Bahasa Pemrograman

19

Haskell Programming Languages

Kita bisa membuat deret aritmatika dengan mudah, misalnya:? [1..10] > [1,2,3,4,5,6,7,8,9,10] ? [2,4..20] > [2,4,6,8,10,12,14,16,18,20]

Kita juga dapat membuat deret tak hingga misalnya [1,3,..], tetapi kalau itu kita lakukan maka interpreter tidak akan pernah selesesai menuliskan anggota deret tersebut (kecuali kalau kita hentikan). Salah satu operasi list yang sederhana adalah penjumlahan list, contohnya:? [1..10] ++ [21..30] > [1,2,3,4,5,6,7,8,9,10,21,22,23,24,25,26,27,28,29,30]

BAB V PERCABANGANV.1 PercabanganStatement if-then-else terdapat di bahasa Haskell. Contoh penggunaannya adalah sebagai berikut:> if 1 < 2 then Satu lebih kecil dua. else Satu tidak lebih kecil dua. ? "Satu lebih kecil dua.

Selain if-then-else, dalam Haskell juga terdapat statement case-of, sebagai contoh:take m ys = case (m,ys) of (0,_) -> [] (_,[]) -> [] (n,x:xs) -> x : take (n-1) xs

Konsep Bahasa Pemrograman

20

Haskell Programming Languages

BAB VI FUNGSIVI.1 FungsiFungsi dapat dibuat dengan menuliskan tipenya, lalu mendefinisikannya. Misalnya:tambahSatu :: Integer -> Integer tambahSatu x = x + 1

Jika kita gunakan fungsinya, inilah outputnya:? tambahSatu 5 > 6 ? tambahSatu 999 > 1000

Baris yang pertama:tambahSatu :: Integer -> Integer

berarti bahwa fungsi yang kita buat bernama tambahSatu, lalu dia menerima input sebuat Integer dan akan mengembalikan nilai Integer. Sebetulnya jika kita tidak menentukan tipe fungsi, interpreter akan menganalisa fungsinya untuk ditentukan tipenya. Walaupun begitu akan lebih jelas bagi pembaca (dan juga meringankan tuga interpreter) jika tipe fungsinya dituliskan oleh kita.

Konsep Bahasa Pemrograman

21

Haskell Programming Languages

Kita bisa lihat bahwa definisi fungsinya sangat mirip dengan notasi matematika untuk fungsi yang sama, yaitu f(x) = x + 1. Catatan: Dalam interpreter Hugs 98, definisi fungsi harus berada di sebuah file teks dan untuk menggunakannya kita harus meload file yang bersangkutan dari Hugs 98. File harus diberi awalan yang menunjukkan nama modul. Sebagai contoh, untuk menggunakan fungsi tambahSatu kita harus memiliki file teks dengan isi sebagai berikut:module Test where tambahSatu :: Integer -> Integer tambahSatu x = x + 1

Jika fungsi tersebut kita save sebagai Test.hs di folder d:\Haskell, maka untuk meloadnya dari Hugs 98 kita harus memasukkan perintah berikut:? :load "D:\Haskell\Test.hs"

Jika filenya kita ubah lalu kita ingin meload ulang dari Hugs 98, maka kita cukup mengetikkan perintah berikut:? :reload

VI.2 Pattern MatchingPerlu diketahui bahwa sebuah modul dapat berisi lebih dari satu definisi fungsi. Sekarang kita akan mendefinisikan fungsi untuk mencari faktorial dari n. Faktorial dari n, untuk n bilangan bulat positif adalah n * (n 1) * (n 2) * ... * 2 * 1 . Faktorial dari 0 adalah 1. penggunaannya:faktorial :: Integer -> Integer faktorial 0 = 1 faktorial n = n * faktorial (n - 1) ? faktorial 3 > 6 ? faktorial 0 > 1

Inilah salah satu cara mendefinisikan fungsinya dan contoh

Di dalam definisinya, fungsi tersebut menggunakan pattern matching dan rekursi. Pattern matching akan dikenakan pada argumen fungsi. Sebagai contoh, misalnya kita

Konsep Bahasa Pemrograman

22

Haskell Programming Languages

memanggil faktorial 3. Pertama dicek apakah argumen match dengan 0. Karena tidak, maka dicek apakah argument match dengan n. Karena n bisa berupa Integer apapun (jenis fungsinya adalah Integer -> Integer), maka 3 match dengan n dan definisi fungsi yang berkaitan digunakan. Sebagai ilustrasi dari fleksibilitas pattern matching di Haskell, fungsi faktorial juga dapat didefinisikan sebagai berikut:faktorial :: Integer -> Integer faktorial 0 = 1 faktorial (n + 1) = (n + 1) * faktorial (n)

Dalam kasus ini, 3 akan match dengan (n + 1), sebab 3 adalah (n + 1) dengann=2.

Fungsi nilaiMutlak di bawah akan menunjukkan penggunaan pattern matching juga:nilaiMutlak :: Integer -> Integer nilaiMutlak x | x >= 0 = x | x < 0 = -x ? nilaiMutlak 0 > 0 ? nilaiMutlak 3 > 3 ? nilaiMutlak -3 > 3

Perhatikan bahwa jika nilai argumen lebih besar atau sama dengan 0, maka argumennya akan dikembalikan, sedangkan jika tidak maka yang akan dikembalikan adalah negatif dari argumennya.

VI.3 ListSelanjutnya kita akan membahas penggunaan list sebagai argumen fungsi.[a]. Untuk membatasi pada list Integer misalnya, digunakan [Integer].

Untuk

menyatakan bahwa fungsi kita dapat menerima/menghasilkan list apapun, digunakan Inilah definisi fungsi yang mengecek apakah sebuah list kosong beserta penggunaannya:listKosong :: [a] -> Bool listKosong [] = True listKosong x = False ? listKosong [] > True ? listKosong [1..10]

Konsep Bahasa Pemrograman

23

Haskell Programming Languages

> False ? listKosong [10..1] > True

Dari contoh di atas kita tahu bahwa list [10..1] ternyata adalah list kosong. Artinya konstruksi list [a..b] akan menghasilkan list tidak jika dan hanya jika a lebih kecil atau sama dengan b. Kita akan mendefinisikan fungsi yang mengembalikan hasil jumlahan semua anggota list.jumlah :: [Integer] -> Integer jumlah [] = 0 jumlah (x:xs) = x + jumlah xs ? jumlah [1, 5, 4] > 10 ? jumlah [1..10] > 55 ? jumlah [] > 0

Kemunculan (x:xs) berarti sebuah list yang elemen awalnya x dan list sisanya xs. Sebagai contoh, list [1, 5, 4] akan match dengan pattern (x:xs) sebab [1, 5, 4] memiliki sebuah elemen awal yaitu 1 dan list sisanya adalah [5, 4]. Kita bisa lihat bahwa sisanya (xs) digunakan lagi sebagai argumen fungsi jumlah. Dengan apa yang telah dipelajari, kita sudah dapat membuat banyak fungsi:balikList :: [a] -> [a] balikList [] = [] balikList (x:xs) = balikList xs ++ [x] ? balikList [1..10] > [10,9,8,7,6,5,4,3,2,1] adaDiList :: [Integer] -> Integer -> Bool adaDiList [] n = False adaDiList (x:xs) n = if x == n then True else (adaDiList xs n) ? adaDiList [1..10] 3 > True ? adaDiList [1..10] 11 > False hilangkan :: [Integer] -> Integer -> [Integer] hilangkan [] n = [] hilangkan (x:xs) n = if x == n then hilangkan xs n elseKonsep Bahasa Pemrograman

24

Haskell Programming Languages

[x] ++ (hilangkan xs n) ? hilangkan [1, 2, 2, 1] 2 > [1,1] ? hilangkan [5, 4, 3, 2, 1] 3 > [5,4,2,1]

Di bawah akan diberikan contoh fungsi-fungsi yang menggunakan konstruksi bahasa yang lebih lanjut lagi. Dengan melihat contoh-contoh di bawah, anda dapat melihat bahwa Haskell adalah bahasa yang ekspresivitasnya sangat tinggi.cartesian :: [Integer] -> [Integer] -> [[Integer]] cartesian x y = [[i,j] | i a awal (x:xs) = x ? awal [2, 3, 4] > 2 sisa :: [a] -> [a] sisa (x:xs) = xs ? sisa [2, 3, 4] [3,4] quicksort [] quicksort (x:xs) = = ++ ++ [] quicksort [y | y printFrom (a + 1) b else print b ? > > > > > > > > > > printFrom 1 10 1 2 3 4 5 6 7 8 9 10

VI.4 Abstraksi Lambda (Lambda Abstractions)Disamping menggunakan menggunakan persamaan untuk menetapkan fungsi, kita juga dapat menggunakan menetapkannya anonim melalui abstraksi lambda. Sebagai

Konsep Bahasa Pemrograman

25

Haskell Programming Languages

contoh, sebuah fungsi ekuivalen dengan inc dapat ditulis sebagai \x -> x+1. Sama seperti fungsi add yang ekuivalen dengan \x -> \y -> x+y. Abstraksi lambda bersarang seperti ini dapat ditulis dengan notasi singkat yang ekuivalen \x y -> x+y. Dalam kenyataannya, persamaan :inc x = x+1 add x y = x+y

adalah kependekan dariinc = \x -> x+1 add = \x y -> x+y

Kita akan membahas lebih banyak mengenai ekuivalensi selanjutnya. Secara umum, diambil bahwa x memiliki jenis t1 dan exp memiliki tipe t2 maka \x->exp memiliki tipet1->t2.

VI.5 Infix OperatorOperator infix merupakan benar-benar fungsi, dan dapat juga didefinisikan melalui persamaan. Sebagai contoh ini adalah definisi dari daftar operator concatenation(++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs++ys)

Secara leksikal, operator infix terdiri seluruhnya dari simbol yang berlawanan dengan pengenal normal yang (2.4). Haskell tidak memiliki operator prefix, dengan pengecualian dari minus(-), yang merupakan infix dan prefix. Sebagai contoh yang lain, operator infix yang penting pada fungsi adalah untuk komposisi fungsi(.) :: (b->c) -> (a->b) -> (a->c) f . g = \ x -> f (g x)

Sections Karena operator infix hanya merupakan fungsi, ini membuatnya bisa diterapkan sebagian dengan baik. Pada Haskell applikasi sebagian dari operator infix disebut section. Sebagai contoh:(x+) _ \y -> x+y

Konsep Bahasa Pemrograman

26

Haskell Programming Languages

(+y) _ \x -> x+y (+) _ \x y -> x+y

Bentuk terakhir dari section diatas mengikat sebuah operator infix pada sebuah nilai fungsional yang ekuivalen. Dan ini adalah mudah saat melewatkan sebuah operator infix sebagai argumen daripada fungsi, Seperti pada map (+)[1,2,3] (pembaca harus mengecek bahwa hal ini mengembalikan daftar dari

fungsi), Juga penting saat memberikan fungsi type signature. Sebagai contoh (++) dan (.) diberikan selanjutnya. Kita sekarang dapat melihat add yang didefinisikan sebelumnya hanyalah(+), dan inc hanyalah (+1)! Sebenarnya definisi dapat berbentuk sesederhana

berikut:inc = (+ 1) add = (+)

Kita dapat mengikat sebuah operator infix dalam nilai fungsional, Tetapi dapatkah kita melewati jalan yang lain? Ya, kita dapat menutup pengikat pengenal pada nilai fungsional pada backquotes. sebagai contoh x add y adalah sama seperti add x y1. Beberapa fungsi membaca lebih baik pada bentuk ini. Sebagai contoh daftar keanggotaan yang belum didefinisikan memperkirakan elem; ekspresi dari x elem xs dapat dibaca secara intuitif sebagai ]\x adalah elemen dari xs." Pada titik ini, pembaca mungkin dibingunkan dengan banyaknya cara untuk mendefinisikan fungsi. Keputusan untuk menyediakan mekanisme ini sebagian menyandarkan pada konsistensi (sebagai contoh, perlakuan pada infix vs fungsi reguler) Fixity Declarations Sebuah deklarasi tetap dapat diberikan untuk setiap operator infix atau constructor (meliputi hal lain yang dibuat dari pengenal umum, seperti elem). Deklarasi ini menetapkan tingkat precedence dari 0 sampai 9 (dengan 9 sebagai yang tertinggi; aplikasi normal diasumsikan memiliki tingkat precedence 10) dan kiri-kanan, atau non associativity. Sebagai contoh deklarasi tetap untuk for ++ dan . adalah:infixr 5 ++ infixr 9 .1

Perhatikan baik-baik bahwa add ditutup dengan tanda petik (backquotes) bukan apostrophes seperti digunakan pada sintak dari karakter; contohnya. 'f' adalah karakter, dimana `f` adalah operator infix. Untungnya, sebagian besat terminal ASCII membedakan cara ini daripada huruf yang digunakan pada manuskrip.

Konsep Bahasa Pemrograman

27

Haskell Programming Languages

Keduanya menetapkan associativity kanan, yang pertaman dengan tingkat presedense dari 5 dan lainya 9. Associativity kiri ditetapkan melalui inifxl dan non associativity dengan infix. Juga fixity dari lebih dari satu operator dapat dispesifikasikan dengan deklarasi fixity yang sama. Jika tidak ada deklarasi tetap yang diberikan untuk sebagian operator, secara default diberikan infixl 9.

VI.6 Functions are Non-strictbot didefinisikan dengan: bot = bot

Dengan kata lain, bot adalah ekspresi non-terminating, Secara abstrak kita menunjukkan nilai dari ekspresi non-terminating sebagai (read bottom"). Ekspresi yang hasilnya dalam bentuk dari run-time errot, seperti 1/0, juga memiliki nilai ini. Beberapa error ini tidak dapat diperbaiki : Program tidak akan meneruskan kesalahan. Error ditangani dengan sistem I/O, seperti kesalahan pada end-of-file dapat diperbaiki dan ditangani dengan cara yang berbeda. (Seperti kesalahan I/O tidaklah benar-benar kesalahan seluruhnya tetapi lebih pada exception). Sebuah fungsi f dikatakan tegas jika, saat diaplikasikan pada ekspresi nonterminating juga gagal untuk melakukan terminasi. Dengan kata lain, f adalah tegas jika nilai dari f bot adalah . Pada kebanyakan bahasa pemrograman semua fungsi adalah tegas. Tetapi hal ini tidak berlaku pada haskell. Sebagai contoh yang sederhana, pandang const1, fungsi constant 1 didefinisikan dengan :const1 x = 1

Nilai dari bot const1 bot pada Haskell adalah 1. Secara operasional, karena const1 tidak membutuhkan nilai dari argumennya, dia tidak berusaha untuk mengevaluasinya. Dan maka dari itu tidak pernah terperangkap pad komputasi nonterminating. Untuk alasan ini, fungsi tidak tegas (non-sctrict) disebut fungsi malas (lazy) dan dikatakan untuk mengevaluasi argumen lazy atau by need. Sejak kesalahan dan nilai nonterminating adalah secara semantik sama pada Haskell, argumen diatas juga menanggung kesalahan. Sebagai contoh, const1 (1/0) juga mengevaluasi pada 1. Fungsi non-strict secara ekstrim berguna dalam berbagai bidang. Manfaat utama adalah membebaskan programmer dari berbagai pertimbangan tentang perintah evaluasi.

Konsep Bahasa Pemrograman

28

Haskell Programming Languages

Nilai hasil komputasi yang mahal, dapat dilewatkan sebagai argumen untuk fungsi tanpa perlu khawatir jika dikomputasikan jika mereka tidak dibutuhkan. Contoh penting dari ni adalah kemungkinan struktur data tak terbatas (infinite). Cara lain untuk menjelaskan fungsi non-strict adalah komputer Haskell menggunakan pendefinisian daripada penugasan yang ditemukan dalam bahasa tradisional. Membaca deklarasi sepertiv = 1/0

Seperti menenetapkan v sebagai 1/0 dari pada mengkomputasikan 1/0 dan menyimpan hasilnya pada v, Hanya jika nilai dari v dibutuhkan dengan kesalahan pembagian nol terjadi. Dengan sendirinya, deklarasi tidak termasuk komputasi manapun. Programming menggunakan assignment membutuhkan perhatian dengan baiki dalam rangka eksekusi. Definisi sebaliknya sangat sederhana. Mereka dapat dipresentasikan dengan berbagai cara tanpa mempengaruhi arti dari program.

VI.7 Struktur Data tak berhinga (Infinite" Data Structures)Satu manfaat dari sifat non-strict dari Haskell adalah data konstruknya adalah non-strict juga. Hal ini tidaklah mengejutkan, karena konstruktor adalah benar-benar hanya bentuk khusus dari fungsi (fitur pembeda ialah bahwa mereka dapat digunakan pada pengenalan pola) Sebagai contoh, konstruktor dari list, (: ) adalah non strict) Konstruktor non-strict mengizinkan definisi struktur data infinite. Ini adalah salah satu list infinite :

ones = 1 : ones

Mungkin lebih menarik adalah fungsi numsFrom:numsFrom n = n : numsFrom (n+1)

Konsep Bahasa Pemrograman

29

Haskell Programming Languages

Demikian numsFrom n adalah list infinite dari integer yang berturut-turut dimulai dari n. Dari sisni kita dapat membangun sebuah list infinite dari square.squares = map (^2) (numsfrom 0)

Sebagai contoh, pindahkan elemen pertama dari list : ambil 5 squares => [0,1,4,9,16] Definisi diatas adalah contoh dari list sirkular. Pada banyak kemalasan (laziness) memilliki dampak penting pada efisiensi. Karena implementasinya dapat diharapkan untuk mengimplementasikan list sebagi struktur sirkular sebenarnya. Demikian dapat menghemat tempat. Untuk contoh lain penggunaan dari circularity, bilangan Fibonaci dapat dikomputasikan secara efisien, seperti pada sequence infinite berikut :fib = 1 : 1 : [ a+b | (a,b) a. Misalnya adalah fungsi odd : Dari tipenya terlihat jika itu mengembalikan nilai dari tipe polymorphis yang mana tidak mengetahui apapun. Karena fungsi tidak pernah menerima nilai dari tipe sebagai argumen. Kenyataannya, hanya ada satu nilai terbagi oleh semua tipe : Memang, secara semantik telah ditetapkan nilai apa yang selalu dikembalikan dengan kesalahan (pemanggilan semua kesalahan memiliki nilai ). Meskipun demikian, kita dapat mengharapkan bahwa sebuah implementasi yang masuk akal akan mencetak argumen string untuk kesalahan dengan tujuan diagnostik. Demikianlah fungsi ini berguna saat

Konsep Bahasa Pemrograman

30

Haskell Programming Languages

kita ingin menterminasi program saat sesuatu telah menjadi salah. Sebagai contoh, definisi aktual dari head yang diambil dari prelude standar adalah:head (x:xs) = x head [] = error "head{PreludeList}: head []"

BAB VII GRAFIKDalam Haskell, kita juga dapat menggambarkan objek 3 dimensi. Penggambaran objek 3 dimensi ini dimungkinkan karena dalam Haskell kita dapat menuliskan pemrograman OpenGL. Contoh:import Graphics.UI.GLUT import Graphics.Rendering.OpenGL main = do (progName,_) vertex$Vertex3 x y z) myPoints myPoints :: [(GLfloat,GLfloat,GLfloat)] myPoints = [(-0.25, 0.25, 0.0) ,(0.75, 0.35, 0.0) ,(0.75, -0.15, 0.0)

Konsep Bahasa Pemrograman

31

Haskell Programming Languages

,((-0.75), -0.25, 0.0)]

Adapun outputnya adalah:

BAB VIII PENUTUPBahasa pemrograman Haskell merupakan bahasa pemrograman yang sangat sederhana dan mudah dipelajari. Hal ini tidak lain disebabkan karena Haskell merupakan bahasa pemrograman fungsional murni. Oleh karena itu Haskell dapat: 6. Meningkatkan produktifitas programmer (Ericsson banyak memanfaatkan hasil percobaan Haskell dalam software telephony) 7. Lebih singkat, lebih jelas dan kode-kodenya mudah dibaca 8. Errornya semakin sedikit dan reabilitynya lebih tinggi 9. Membuat jarak antara programmer dengan bahasa itu lebih pendek 10. Waktu untuk membuat program menjadi lebih singkat Selain itu, dalam Haskell tidak ada varibel yang berubah, tidak ada efek samping dari penggunaan sebuah fungsi, tidak ada perulangan, dan tidak ada program order. Akan tetapi, Haskell sendiri kurang dikenal dibandingkan bahasa-bahasa pemrograman terstruktur. Hal ini disebabkan karena gaya berfikir seorang programmer, terutama programmer yang terbiasa menggunakan bahasa pemrograman terstruktur, harus sedikit diubah ketika ia ingin membuat program dengan menggunakan Haskell. Selain itu, Haskell punya beberapa kelemahan, antara lain: 3. kode programnya cenderung agak lambat berkembang dibanding program yang sama yang ditulis dalam bahasa seperti CKonsep Bahasa Pemrograman

32

Haskell Programming Languages

4. Haskell cenderung sulit untuk didebug. Jadi, dengan semua kelebihan dan kekurangannya, apakah anda tertarik untuk membuat program dalam bahasa Haskell?

DAFTAR PUSTAKAhttp://www.mta.ca/~rrosebru/oldcourse/371199/haskell http://haskell.org http://haskell.org/ghc http://haskell.org/hugs http://www.isi.edu/~hdaume/htut/ haskell.pdf haskell98-tutorial.pdf

Konsep Bahasa Pemrograman

33