Pertanyaan di atas seringkali saya temukan, baik dari orang-orang yang baru mulai terjun ke dunia pemrograman maupun dari orang-orang yang sudah sangat berpengalaman dalam pengembangan perangkat lunak. Ada yang berpendapat bahwa menguasai banyak bahasa pemrograman tidak penting karena satu bahasa saja sudah cukup untuk segala jenis pekerjaan, tetapi ada juga yang berkata menguasai semakin banyak bahasa semakin baik. Saya tidak setuju dengan keduanya. Kenapa? Tulisan ini akan menjelaskan kenapa, dan apa pendapat saya mengenai penguasaan banyak bahasa pemrograman.

Kenapa Ada Banyak Bahasa Pemrograman?

Sebelum memulai pembahasan mengenai penguasaan banyak bahasa, tentunya kita harus mengerti alasan mengapa ada banyak bahasa pemrograman terlebih dahulu. Seperti segala hal yang ada dalam dunia komputer, terdapat sangat banyak bahasa pemrograman. Dunia komputer memang memiliki kecenderungan untuk membuat banyak hal yang saling bertentangan, yang masing-masing memiliki pengikut fanatiknya. Vim dan Emacs. Mac dan PC. iOS dan Android. Bahkan, Nerd dan Geek.

The definitions I grew up with were that a geek is someone unusually into something (so you could have computer geeks, baseball geeks, theater geeks, etc) and nerds are (often awkward) science, math, or computer geeks. But definitions vary.

Oke, seriusnya, ada beberapa alasan kenapa diciptakan banyak bahasa pemrograman. Alasan pertamanya, karena bahasa pemrograman yang ada tidak dapat memenuhi kebutuhan dari penggunanya. Misalnya, bahasa pemrograman Java diciptakan untuk memenuhi keinginan para programmer agar dapat menulis kode yang berjalan dalam banyak platform dengan mudah (jargon yang dibawa oleh Java adalah: Write Once, Run Anywhere). Bahasa C maupun C++ yang populer pada masa itu tidak dapat memenuhi hal ini, karena banyaknya sistem operasi tertutup pada masa itu, di mana masing-masing vendor memiliki cara tersendiri untuk berinteraksi dengan sistem.

Alasan selanjutnya adalah karena adanya permasalahan yang memerlukan cara penyelesaian yang unik. Seperti kata pribahasa programmer,

when all you have is hammer, everything starts to look like a nail

Contoh klasik dari pribahasa ini ini adalah QuickSort. Algoritma ini dirancang untuk menggantikan Shell Sort dengan memanfaatkan fungsi rekursif, yang juga adalah signature dari pemrograman fungsional. Untuk mempermudah ilustrasi, berikut adalah kode implementasi QuickSort menggunakan metode imparatif:

def sort(a: Array[Int]) {

  def swap(i: Int, j: Int) {
    val t = a(i); a(i) = a(j); a(j) = t
  }

  def sort1(l: Int, r: Int) {
    val pivot = a((l + r) / 2)
    var i = l
    var j = r
    while (i <= j) {
      while (a(i) < pivot) i += 1
      while (a(j) > pivot) j -= 1
      if (i <= j) {
        swap(i, j)
        i += 1
        j -= 1
      }
    }
    if (l < j) sort1(l, j)
    if (j < r) sort1(i, r)
  }

  if (a.length > 0)
    sort1(0, a.length - 1)
}

dan berikut adalah kode yang diimplemenatsikan dengan metode fungsional:

def sort(a: List[Int]): List[Int] = {
  if (a.length < 2)
      a
  else {
    val pivot = a(a.length / 2)
    sort(a.filter(_ < pivot)) :::
         a.filter(_ == pivot) :::
         sort(a.filter(_ > pivot))
  }
}

Jelas kenapa metode fungsional lebih cocok digunakan dalam kasus ini? Lebih singkat, sederhana, dan jelas apa yang dilakukan. Ngomong-ngomong, kedua kode di atas diambil dari contoh implementasi kode Scala yang ada di sini dan sini. Bagi yang tertarik, sejarah mengenai QuickSort dapat dibaca di salah satu literatur klasik ilmu komputer, “The Emperor’s Old Clothes” karya Hoare.

Sebaliknya contoh masalah yang diselesaikan dengan mudah oleh bahasa yang bersifat imparatif adalah IO (Input/Output). Dalam bahasa fungsional murni (misal: Haskell) tidak diperbolehkan terdapat side effect apapun. “Side effect” maksudnya adalah perubahan terhadap sesuatu (bisa nilai variabel, state, atau apapun) di luar fungsi yang dilakukan di dalam fungsi tersebut. Contoh dari side effect adalah jika sebuah fungsi mengubah variabel global atau nilai di luar fungsi tersebut. Lihat contoh berikut:

var a: Int = 1 // a = 1
def sideEffect(value: Int) = {
  a = a + value
  a
}
sideEffect(10) // a = 11

Fungsi di atas dikatakan memiliki side effect karena pemanggilan fungsi tersebut mengubah variabel yang ada di luar fungsi. Dengan definisi seperti itu, tentunya secara alami IO (yang selalu mengubah sesuatu di luar fungsi: terminal atau media apapun yang menjadi tempat IO) memberikan side effect. Solusi dari para pengembang bahasa fungsional? Monad. Sebagai ilustrasi tingkat kerumitan Monad, saya belum pernah bertemu orang yang dapat mengerti Monad dengan hanya membaca satu artikel saja. Butuh waktu lama dan banyak eksperimen untuk benar-benar mengerti Monad. Yes, it is that complicated. Karena hal ini juga maka saya memandang Scala sebagai bahasa yang ideal (untuk saya). Scala melakukan penggabungan antara paradigma orientasi objek dan fungsional, kemudian menggunakannya pada tempat yang semestinya. Best of both worlds.

Kenapa Harus Menguasai Banyak Bahasa Pemrograman?

“Oke bert, jelas deh kenapa perlu ada banyak bahasa pemrograman. Terus kenapa gue harus menguasai banyak bahasa pemrograman?”

Ini pertanyaan yang lumayan sering ditanyakan ke saya. Jawabannya sangat sederhana, dan juga dibahas mendetail dalam salah satu literatur klasik ilmu komputer juga (“The Humble Programmer” oleh Dijkstra dan “An Interview with Edsger W. Dijkstra” oleh P. Frana). Jawaban dari pertanyaan di atas adalah: bahasa pemrograman yang kita gunakan berpengaruh dalam cara kita menyelesaikan masalah. Kalau kita hanya mengerti orientasi objek, maka segala permasalahan (termasuk yang cocok diselesaikan dengan imparatif) akan kita selesaikan dengan paradigma OO. Tidak ideal pastinya.

Tapi menguasai banyak bahasa pemrograman juga terlalu makan banyak waktu dan tidak praktikal. Perlu bertahun-tahun hanya untuk benar-benar mengetahui sebuah bahasa pemrograman. Misalnya, programmer C yang tidak mengerti kenapa kode berikut:

while(*dst++ = *src++);

melakukan pengkopian String dan kenapa kode di atas sangat buruk bukanlah seorang yang menguasai bahasa C. Orang tersebut mungkin tahu dan mengerti paradigma C, tetapi jelas tidak menguasai bahasa C. Dan penguasaan sampai level tersebut akan sangat sulit untuk dilakukan. Perlu banyak pengalaman dalam mengembangkan perangkat lunak yang berukuran besar dan digunakan banyak orang. Pengalaman tersebut hanya bisa didapatkan dalam dunia akademis atau bisnis. Tapi dosen (atau manajer) mana yang akan memberikan lampu hijau untuk menggunakan Haskell, OCaml, Clojure, atau bahasa unik lainnya dalam proyek yang bernilai besar?

Karena hal ini juga saya tidak setuju dengan orang yang berkata bahwa kita harus menguasai banyak bahasa pemrograman atau satu bahasa pemrograman saja sudah cukup. Jelas kita perlu tahu banyak bahasa, minimal satu bahasa untuk setiap paradigma, tetapi akan sangat tidak praktis (atau bahkan tidak mungkin sama sekali) untuk menguasai banyak bahasa pemrograman. Yang kita perlukan dari mempelajari berbagai paradigma adalah sudut pandang baru untuk menyelesaikan masalah. Ingat, pada dasarnya programmer itu dibayar untuk menyelesaikan masalah. Dan sebuah solusi yang baik adalah solusi yang mempertimbangkan berbagai sudut pandang untuk menyelesaikan sebuah masalah. Sebagai ilustrasi, apakah kamu berani berobat ke seorang dokter yang melakukan operasi untuk mengobati semua penyakit (termasuk masuk angin)? Apakah kamu mau menjadi seorang dokter (atau programmer) yang seperti itu? I don’t, obviously.

Bacaan lanjutan: “The Perils of Java Schools” karya Joel Spolsky.

comments powered by Disqus

Daftar Isi