Wednesday, 20 March 2013

LISP

Filled under:


LISP


Bahasa pemrograman LISP adalah bahasa pemrograman yang mengikuti kaidah pada Algoritma Euclidean. Bahasa pemrograman ini menggunakan struktur data sederhana yang disebut sebagai list, bersama dengan operator-operator sederhana dan notasi fungsi. Dengan adanya struktur list tersebut, struktur algoritma dalam bahasa pemrograman LISP dapat direpresentasikan dalambentuk pohon (tree).
Struktur Data dalam Pemrograman LISP
Struktur pemrograman LISP terdiri kode-kode dan data yang membentuk suatu ekspresi. Ekspresi ini dapat berupa sebuah atom, yaitu deretan satu atau beberapa karakter, atau sebuah list yang terdiri dari beberapa ekspresi dan boleh kosong. Di bawah ini beberapa contoh ekspresi dalam LISP :
aaa
()
(aaa)
(abc def)
(a b (c) d)
LISP bekerja dengan menempatkan sebuah ekspresi sebagai operator di awal fungsi, dan diikuti oleh argumen-argumen atau operand-operand di belakangnya. Secara umum direpresentasikan sebagai berikut :
(operator operand1 operand2 operand3 ...)
Operand yang dioperasikan dapat berupa sebuah list yang di dalamnya terdapat sebuah fungsi lain. Apabila kita wakilkan operator dengan X dan operand dengan bilangan bulat maka bentuk diatas dapat menjadi sebagai berikut :
(X 1 2 3 ...)
Dimana 1 mengandung (X 4 5 6 ...) dan memberikan bentuk keseluruhan (X (X 4 5 6 ...) 2 3 ...). Ini merupakan konsep yang sama dengan operasi dalam Algoritma Euclidean, sederhana tapi sangat efisien untuk digunakan.
Algoritma Euclidean dalam LISP
Berikut ini adalah realisasi Algoritma Euclidean
dalam notasi pseudo-code [1]:
procedure Euclidean (input m, n : integer, output PBB
: integer)
{
Mencari PBB (m, n) dengan syarat m dan n bilangan
tak negatif dan m ≥ n
Masukan : m dan n, m ≥ n, dan m, n ≥ 0
}
Deklarasi
r : integer
Algoritma
while n ≠ 0 do
r ← m mod n
m ← n
n ← r
endwhile
{
n = 0, maka PBB (m, n) = m
}
PBB ← m
Untuk lebih jelasnya, berikut ini adalah contoh aplikasi algoritma tersebut. Kita berikan masukan untuk algoritma tersebut bilangan integer 50 dan 7.
Maka hasilnya adalah sebagai berikut :
m ← 50
n ← 7
n ≠ 0
r ← 50 mod 7 = 1
m ← 7
n ← 1
n ≠ 0
r ← 7 mod 1 = 0
m ← 1
n ← 0
n = 0
stop
PBB = m
Aplikasi dari Algoritma Euclidean ini dapat kita lihat ketika kita memroses sebuah fungsi dalam LISP dimana operand yang ada mengandung fungsi lain yang harus dioperasikan terlebih dahulu. Kita akan melihat contoh kasusnya pada operasi aritmatika
dengan input berikut :
(+ (- 9 7) (* 1 8))
Struktur Data Tree dalam LISP
Secara umum, bentuk sebuah fungsi dalam LISP adalah sebuah list berisi operand-operand berupa ekspresi, dan kesemua operand tersebut berpusat pada operator yang diletakkan di awal list tersebut. Karena semua operand dioperasikan bergantung pada operator yang ada, maka kita dapat mengandaikan sebuah hubungan subordinasi antara operator dan operand dalam suatu fungsi, dimana operator akan menempati posisi yang lebih tinggi (menjadi “parent”), sedangkan operand menempati posisi yang lebih rendah (menjadi “children”).
LISP menyimpan bentuk data berupa list sebagai bagian dari sebuah pohon dalam komputer dengan setiap elemennya berisi sebuah address dan decrement. Sebuah elemen dalam list dapat kita representasikan sebagai kotak yang mengandung dua elemen tersebut.
Sebuah list dapat diekspresikan dengan menggunakan sebuah pointer yang mengacu pada car (elemen pertama) dari ekspresi list tersebut, dan memberikan pointer yang mengacu pada cdr (elemen sisanya) dari list tersebut. Sebuah list juga dapat mengandung subekspresisubekspresi
yang sama, misalnya ((M .N ) X (M . N).
Dengan hubungan tersebut, sebuah list tidak perlu didefinisikan dua kali. Apabilaterdapat list yang identik dengan list yang telah didefinisikan, maka untuk memanggil list tersebut cukup dengan mengacu kepada pointer tempat list tersebut berada. Sebuah list juga dapat berupa list sirkuler. List seperti ini tidak umum digunakan, tetapi bisa muncul sebagai hasil dari operasi tertentu. Beberapa keuntungan menggunakan struktur data tree seperti ini antara lain :
1. Dengan menggunakan metode susunan tree seperti ini, maka ukuran dan jumlah ekspresi yang akan ditangani oleh program tidak perlu ditentukan dari awal. Struktur data tree ini memungkinkan operasi dengan ekspreseiekspresi yang terus membesar.
2. Register yang sudah selesai digunakan dapat langsung dikosongkan, sehingga dapat menghemat memori yang terpakai saat menjalankan program. Apabila struktur data disimpan secara linier, maka akan sulit untuk ditentukan kapan register yang dipakai di dalam fungsi dapat dikembalikan untuk dipakai dalam proses-proses lain.
3. Sebuah ekspresi yang menjadi subekspresi dari ekspresi lainnya hanya perlu
dialokasikan sekali saja.
Salah satu kekuatan dalam bahasa pemrograman LISP adalah kemampuan untuk menerima definisi fungsi yang menggunakan fungsi dari dirinya sendiri. Fungsi seperti ini disebut fungsi rekursif. Hal seperti ini bisa dilakukan dengan memanggil nama atau label dari fungsi tersebut (apabila telah didefinisikan sebelumnya) di dalam fungsi itu sendiri, atau dengan cara tidak langsung, menggunakan definisi fungsi berantai yang akan berujung pada fungsi-fungsi yang asli. Fungsi ini mengikuti kaidah Algoritma Euclidean dimana fungsi tersebut akan mengulangi dirinya sendiri terhadap hasil operasinya apabila hasil yang diinginkan belum terpenuhi. Penggunaan fungsi rekursif ini sangat efisien, karena kita tidak perlu mendefinisikan fungsi baru untuk menjalankan proses yang sama berulangkali. Dengan demikian proses coding dapat dipercepat dan memori yang diperlukan untuk menyimpan program dapat dihemat.
Salah satu contoh penggunaan fungsi rekursif ada pada fungsi pencarian/search. Berikut ini contoh fungsi search sederhana sebuah atom dalam sebuah list menggunakan fungsi car dan cdr dalam LISP. Fungsi car adalah fungsi yang akan mengembalikan elemen pertama dari suatu list. Elemen pertama tersebut adalah ekspresi yang berupa atom ataupun list. Sedangkan fungsi cdr adalah kebalikan dari fungsi car. Fungsi cdr akan mengembalikan nilai suatu list kecuali elemen pertamanya. Fungsi search dalam notasi pseudo-code adalah sebagai berikut.
function search (input x : list, y : atom output :
boolean)
while search ← false do
car x
if car x = y then
true
{
Mengembalikan nilai true apabila nilai y
yang dicari terdapat dalam car x
}
else
search cdr x
{
Melakukan search terhadap elemen sisanya
apabila y belum didapati
}

Fungsi search di atas akan mencocokkan atom pertama yang ditemukan dalam list yang dioperasikan dengan atom y yang dicari. Apabila atom y tersebut sama dengan elemen pertama dari list, maka fungsi akan mengembalikan nilai true. Sedangkan apabila atom y belum ditemukan, maka fungsi akan mencari di dalam sisa dari list tersebut setelah diambil atom pertamanya pada operasi sebelumnya.

0 comments:

Post a Comment