• Tidak ada hasil yang ditemukan

Lists, Streams and Tuples

Dalam dokumen Buku bhs pemrograman Q Equational 2018 (Halaman 46-49)

4 Skript dan Modul

6.3 Lists, Streams and Tuples

Bahasa Q menyediakan tiga construct umum yang berhubungan erat (closely related general constructs) untuk mewakili urutan object: lists, streams dan tuples.

Kita memulai tugas dengan suatu diskusi menyangkut list struktur data. Constant [] menandakan list yang kosong itu. Secara umum, suatu list terdiri dari elemen-elemen X1, X2,..., Xn ditandai [ X1,X2,...,Xn]. Sebagai contoh, [a,b,c] terdiri dari tiga elemen (simbol) a, b dan c. Berlawanan dengan bahasa yang bertipe statistik seperti Haskell dan ML, anggota list mungkin mempunyai tipe berbeda; e.g., [a,10,"a string"] adalah suatu list yang dibentuk dengan baik secara sempurna terdiri dari suatu simbol, suatu number dan suatu string. Ini juga memungkinkan untuk mempunyai lists tersarang/nested, seperti di [a,[b,c]] yang terdiri dari dua elemen, simbol a dan list [b,c].

Kamu juga dapat mempunyai suatu tanda koma diakhir di dalam suatu list, seperti di [a,b,c,]. tanda koma yang diakhir diabaikan, sehingga di atas sama persis halnya seperti [a,b,c]. Hal ini memungkinkan untuk mem-format suatu list sebagai berikut, yang membiarkan kamu menambahkan item baru pada bagian akhir dengan mudah:

def ITEMS = [

"This is the first item", "This is the second item", ...

...

"This is the last item", ];

Seperti di Prolog, lists benar-benar diwakili dalam suatu pertunjukkan right-recursive pertunjukan yang menggunakan suatu pembangun/constructor biner[|] yang mengambil sebagai argumentnya unsur head/kepala dari list dan list unsur-unsur sisa[nya], disebut tail/ekor dari list. Dengan begitu, e.g., [a,b,c] adalah sederhananya suatu notasi stenografi untuk [a|[b,c]], yang menandakan suatu list dengan head/kepala dan tail/ekor [b,c] (yang pada gilirannya adalah suatu stenografi untuk [b|[c]], dll.). Kamu dapat juga mencampur kedua gaya notasi; sebagai contoh, [a,b|[c,d]] adalah cara lain untuk menghadirkan list 4-element [a,b,c,d].

Catat bahwa [a|[b,c]] itu berbeda dari [a,[b,c]]: format yang awal menandakan suatu list three- element, sedangkan yang selanjutnya adalah suatu list two-element yang secara kebetulan anggota kedua menjadi suatu listnya sendiri. Juga catat bahwa constructor [|] sesungguhnya bisa diberlakukan bagi sejumlah pasangan nilai (nilai yang kedua tidaklah harus suatu list); e.g., [a|b] adalah suatu expression/ungkapan yang dibentuk dengan baik secara sempurna (walaupun panjang built-in (built-in length) nya, memberikan index dan menggabungkan operasi yang diuraikan di Bagian 6.4.6 [Operator String List dan Tuple], halaman 46, akan gagal pada nilai- nilai seperti itu).

Q juga menyediakan yang disebut enumerations (penyebutan satu per satu) untuk membangun list dari suatu rentang nilai. Ini pada umumnya mengambil format [X1,X2,...,Xn..Y] yang hanya

merupakan “syntactic sugar” untuk aplikasi enum [X1,X2,...,Xn] Y menyertakan fungsi built-in enum (built-in enum function), lihat Bagian 8.3 [Enumeration Types], halaman 76, untuk detil.

“Syntactic sugar” juga disediakan untuk pengertian list, yang dibahas di Bagian 11.8 [Pengkondisian /Conditionals dan Pengertian/Comprehensions], halaman 127.

Streams terlihat persis seperti list kecuali jika ditulis dengan kurung kurawal. Perbedaan antara lists dan streams adalah pada head/kepala dan tail/ekor dari suatu stream tidak dievaluasi sampai nilai-nilai mereka benar-benar diperlukan selama keadaan suatu perhitungan. Sebagai contoh, kamu akan temukan bahwa jika kamu masukan suatu expression/ungkapan seperti {1+1,2+2,3+3} di dalam interpreter, kemudian nilai dari expression/ungkapan itu hanya akan menjadi expression/ungkapannya sendiri, sebab aplikasi yang ditempelkan (embedded

applications) dari operator ‘+’ tidak dievaluasi: ==> {1+1,2+2,3+3}

{1+1,2+2,3+3}

Di dalam kontras, jika kamu masukan urutan yang sama sebagai list, elemen-elemennya akan dievaluasi dengan seketika:

==> [1+1,2+2,3+3] [2,4,6]

Suatu element stream akan dievaluasi secara otomatis ketika diakses, e.g., menggunakan operator index:

==> {1+1,2+2,3+3}!1 4

Ini juga dikenal sebagai evaluasi “lazy”: evaluasi dari elemen-elemen stream ditunda sampai mereka benar-benar diperlukan. Sesungguhnya, keseluruhan tail/ekor dari suatu stream mungkin ditunda, yang memungkinkan untuk menciptakan urutan tanpa batas (infinite sequences) yang anggota-anggotanyanya diproduksi “on the fly”selama melintasi urutan itu.

Streams diterapkan dalam terms/kaitan yang disebut “format khusus” yang akan diperkenalkan

di Bab 9 [Format Khusus], halaman 83. Kita oleh karena itu menunda suatu deskripsi/uraian yang mendekati tentang struktur data ini sampai Bagian 9.2 [Pembangun/constructor Khusus], halaman 86. Juga catat bahwa bahasa Q-nya sendiri hanya menggambarkan constructor/pembangun stream; hampir semua fungsi stream benar-benar diterapkan oleh script standard library stream.q, lihat Bagian 11.7 [Streams], halaman 126.

Tuples juga bekerja di pertunjukan yang hampir sama seperti list: constant () menandakan tuple yang kosong, dan suatu tuple terdiri dari elemen-elemen X1, X2,..., Xn ditulis seperti (X1,X2,...,Xn), yang setara dengan (X1|(X2|...|(Xn|()))), di mana notasi (X|Xs) menandakan suatu tuple terdiri dari suatu elemen pertama X dan tuple Xs dari elemen-elemen sisa[nya]. Suatu tanda koma diakhir boleh mengikuti elemen tuple yang terakhir, sedemikian sehingga (a,b,c,) adalah sama halnya seperti (a,b,c). Tanda koma diakhir bersifat optional dalam semua kasus kecuali satu: Seperti di bahasa pemrograman Python, 1- tuples ditandai dengan suatu tanda koma diakhir, untuk mencirikannya dari expression/ungkapan parenthesized biasa. Karenanya (a,) menandakan 1-tuple dengan anggota tunggal a, selama (a) hanya menandakan dirinya sendiri.

Catat bahwa berlawanan dengan bahasa seperti ML dan Haskell, tuples tidak benar-benar diperlukan untuk menghadirkan urutan nilai dengan tipe yang berbeda, seperti list struktur data Q telah mengijinkan kamu untuk melakukan itu. Perbedaan yang besar antara list dan tuples di dalam bahasa Q adalah bahwa, selama list selalu diwakili sebagai object data berulang/recursive menggunakan suatu simbol constructor/pembangun biner (hanya cara bagaimana mereka ditulis), tuples benar-benar diterapkan seperti “vektor” yang disimpan sebagai urutan yang berdekatan (contiguous sequences) di dalam memori. (Ini hanya bekerja untuk tuples “yang

dibentuk dengan baik” . Jika tail/ekor Xs dari suatu tuple (X|Xs) adalah bukan suatu tuple, maka

nilai ini hanya dapat diwakili dengan menggunakan suatu aplikasi yang tegas/eksplisit (explicit application) dari constructor/pembangun tuple (tuple constructor).) Oleh karena itu tuples secara normal sangat sedikit menghabiskan memori dibanding list dengan ukuran yang sama, dan mereka juga mengijinkan constant-time mengakses anggota mereka. Ukuran dari suatu tuple dapat ditentukan dalam waktu yang tetap juga. Dalam kontras, operasi yang sama, ketika diberlakukan pada suatu list, memerlukan waktu yang sebanding dengan ukurannya. Pada sisi lain, list menjadi lebih efisien ketika mengakses tail/ekor dari suatu list dan ketika suatu elemen baru di-prepended pada suatu list, yang dapat kedua-duanya dilakukan dalam waktu yang tetap. Di sini suatu tuple memerlukan waktu yang sebanding dengan ukurannya, karena urutan anggota dari tuple yang asli harus dicopy ketika mengakses tail/ekornya atau ketika prepending suatu elemen.

Tradeoffs ini harus dipertimbangkan secara hati-hati ketika memutuskan apakah untuk menerapkan urutan yang ditentukan sebagai list atau suatu tuple. Tuples biasanya adalah pilihan

yang terbaik untuk menerapkan urutan yang fixed menuntut akses acak yang cepat (fast random access) ke anggota individu-nya, sedangkan lists menyediakan penyajian yang paling efisien jika elemen-elemennya ditraverse dan dimanipulasi secara berurutan/sekuen. Jika perlu, kamu bisa dengan mudah mengkonversi antara dua penyajian ini menggunakan fungsi builtin list dan tuple, lihat Bagian 10.4 [Fungsi Konversi (Conversion Functions)], halaman 95.

Lists, streams dan tuples sering dikombinasikan untuk menciptakan struktur tersarang (nested structures) seperti suatu tuple lists dan/atau streams, suatu list (atau stream) dari lists, atau suatu list (atau stream, atau tuple) dari tuples. Construct selanjutnya (urutan tuples) menjadi sangat

umum bahwa Q menyediakan pendukungan khusus untuk itu dalam wujud “pengelompokan”

sintaks. Notasi [X1, X2,...; Y1, Y2,...;...] adalah suatu stenografi untuk [(X1, X2,...), (Y1, Y2,...),...]. Catat bahwa harus ada sedikitnya satu elemen pada setiap kelompok (tetapi sejumlah elemen dalam kelompok yang berbeda boleh bertukar-tukar), dan di sana harus sedikitnya satu

kelompok (kelompok tunggal ditandai dengan suatu akhir ‘;’). Dengan begitu, sebagai contoh,

[A,B;C,D;X,Y,Z] adalah sama halnya seperti [(A,B),(C,D),(X,Y,Z)], dan [X,Y,Z;] sama halnya seperti [(X,Y,Z)]. Notasi yang sama juga berlaku bagi streams dan tuples.

Dalam dokumen Buku bhs pemrograman Q Equational 2018 (Halaman 46-49)