Erlang: #3 and #4 of 99 Lisp Problems

Di Erlang From 99 Lisp Problems terdapat contoh dasar-dasar kode Erlang, namun tidak ada pembahasan bagaimana cara kerja dari kode-kode tersebut. Pada post ini saya akan membahas problem 3 dan problem 4. Problem-problem yang lain akan saya bahas di lain waktu.

Problem 1 dan 2 bisa dilihat di sini. Bila anda mendapati ada simbol-simbol yang tidak saya bahas di sini (seperti [H|T], [_|T], dsb) bisa di baca di tulisan-tulisan saya sebelumnya.

Problem 3. Element at

element_at(L,1) -> hd(L);
element_at([_|T],Pos) -> element_at(T,Pos - 1).

Input list adalah [a,b,c,d], sehingga L = [a,b,c,d]. Kita akan mencari elemen ke-3 dari list tersebut dengan perintah melalui shell nama_modul:element_at(L,3). Urutan list dimulai dari 1 dan bukan 0. Ini ditunjukkan pada fungsi element_at(L,1). hd() adalah built-in function (BIF) untuk mencari kepala (urutan pertama) dari list. Cara kerja program di atas secara berurutan adalah sebagai berikut:

Catatan: urutan angka yang mengandung huruf “a” menggunakan fungsi element_at(L,1) sedangkan “b” menggunakan element_at([_|T],Pos).

1a. tidak digunakan.
1b. element_at([a,b,c,d], 3) -> element_at([b,c,d], 2).

2a. tidak digunakan.
2b. element_at([b,c,d], 2) -> element_at([c,d], 1).

3a. element_at([c,d], 1) -> hd(c,d) -> c.
3b. tidak digunakan.

Problem 4.a. Length list

len([]) -> 0;
len([_|T]) -> 1 + len(T).

Masih menggunakan input L = [a,b,c,d], program dijalankan dengan perintah melalui shell nama_modul:len(L). Cara kerja program di atas secara berurutan adalah sebagai berikut:

Catatan: urutan angka yang mengandung huruf “a” menggunakan fungsi len([]) -> 0 , sedangkan “b” menggunakan len([_|T]) -> 1 + len(T).

1a. tidak digunakan karena input bukan berupa list kosong.
1b. len(a,b,c,d) -> 1 + len(b,c,d]).

2a. tidak digunakan.
2b. 1 + len(b,c,d) -> 1 + 1 + len(c,d) -> 2 + len(c,d)

3a. tidak digunakan.
3b. 2 + len(c,d) -> 2 + 1 + len(d) -> 3 + len(d)

4a. tidak digunakan.
4b. 3 + len(d) -> 3 + 1 + len([]) -> 4 + 0 -> 4.

len(d) hanya mempunyai kepala dan tidak memiliki ekor sehingga ketika menggunakan fungsi len([_|T]) -> 1 + len(T) akan tampak sebagai berikut len(d) -> 1 + len([]) -> 1 + 0 -> 1.

Problem 4.b. Length list with fold

lenf(L) -> lists:foldl(fun(_,Len)-> 1 + Len end, 0, L).

Erlang mempunyai banyak libraries yang terdiri dari modul-modul. Kita akan menggunakan modul lists yang telah disediakan oleh Erlang. Modul lists mempunyai fungsi foldl/3 (fungsi foldl yang memiliki 3 argumen) yang akan digunakan pada contoh program kali ini. Sebelumnya akan saya uraian dulu pemakaian fungsi lists:foldl/3:

lists:foldl/3 mempunyai 3 argumen:

  • foldl/1 (argumen ke-1) diisi dengan fungsi yang memiliki 2 argumen misalnya fun(X,Sum)-> X + Sum.
  • foldl/2 (argumen ke-2) diisi dengan nilai awal untuk argumen ke-2 dari fungsi fun(X,Sum). Kalau nilainya 0 maka fun(X,0).
  • foldl/3 (argumen ke-3) diisi dengan list yang akan diproses mulai dari kiri. Jika ada list [1,2,3,4] maka akan diproses mulai dari angka 1. Sekedar info, pada lists:foldr/3, list akan di proses mulai dari kanan

Sekarang mari kita lihat cara kerja contoh program yang dijalankan melalui shell dengan perintah nama_modul:lenf(L) secara berurutan:

1. lists:foldl(fun(a,0) -> 1 + 0 end, 0, [a,b,c,d]) -> 1
2. lists:foldl(fun(b,1) -> 1 + 1 end, 0, [b,c,d]) -> 2
3. lists:foldl(fun(c,2) -> 1 + 2 end, 0, [c,d]) -> 3
4. lists:foldl(fun(d,3) -> 1 + 3 end, 0, [d]) -> 4

Variabel L dari bentuk [a,b,c,d]menjadi [d]cuma untuk mempermudah pemahaman saja dan tidak berarti variable L berubah elemennya. He…he.. agak ribet. Kalau nggak ada yang protes aku biarin aja deh.

Missed? Make a Dot Prefixed Directory Name

Benar-benar sontoloyo… Cukup lama juga aku mencoba membuat nama direktori di Windows yang ada titik di depannya menggunakan Explorer. Ternyata nggak bisa. Eee.. jebule mesti pake command prompt. Dasar katrok!

makedotdir

Erlang: #1 and #2 of 99 Lisp Problems

Saya melihat Erlang From 99 lisp problems terdapat beberapa contoh dasar-dasar kode Erlang, namun tidak ada pembahasan bagaimana cara kerja dari kode-kode tersebut. Pada post ini saya akan membahas problem 1 dan problem 2. Problem-problem yang lain akan saya bahas di lain waktu.

Problem 1: Last element

myLast([H]) -> H;
myLast([_|T]) -> myLast(T).

Misalnya kita akan mencari elemen terakhir dari list [1,2,3,4]. Cara kerja program di atas secara berurutan adalah sebagai berikut:

1. myLast(1,2,3,4) -> myLast(2,3,4)
2. myLast(2,3,4) -> myLast(3,4)
3. myLast(3,4) -> myLast(4)
4. myLast(4) -> 4.

No.1 tidak dapat menggunakan fungsi myLast([H]) -> H karena jumlah elemen list lebih dari 1. Tanda “_” pada myLast([_|T]) artinya “don’t care”-pattern (bukan variable). No. 1 – 3 menggunakan fungsi myLast([_|T]) -> myLast(T), sedangkan no. 4 menggunakan fungsi myLast([H]) -> H;

Kalau belum paham tentang [H|T], bisa baca di sini. Hati-hati, tidak usah terlalu berpikir keras, karena memang sesederhana itu memahaminya. Bagi yang belum terbiasa dengan kode di atas, tolong cara berpikir model C, C++, C#, Java dilepas dulu sementara.

Problem  2: Second last element

Fungsi ini berguna untuk mencari nilai kedua dari belakang dari sebuah list.

mySecondLast([H,_]) -> H;
mySecondLast([_|T]) -> mySecondLast(T).

Cara kerja program tersebut secara berurutan dengan input [1,2,3,4] adalah sebagai berikut:

1a. tidak digunakan karena input memiliki lebih dari 2 elemen.
1b. mySecondLast(1,2,3,4) -> mySecondLast(2,3,4)

2a. lihat alasan 1a.
2b. mySecondLast(2,3,4) -> mySecondLast(3,4)

3a. mySecondLast(3,4) -> 3.
3b. tidak dipakai.

Pada tiap nomor yang memiliki huruf a berarti dia menggunakan fungsi mySecondLast([H,_]) -> H, sedang huruf b menggunakan fungsi mySecondLast([_|T]) -> mySecondLast(T).