- Perbedaan dalam kumpulan pola dasar lebih penting daripada sintaks individual, dan bahasa pemrograman terbagi menjadi tujuh bahasa purwa menurut cara pengulangan, rekursi, dan penyusunan program
- Bahasa baru yang berbagi bahasa purwa yang sudah akrab akan lebih mudah dipelajari, tetapi berpindah ke purwa yang asing membutuhkan jalur berpikir baru dan waktu belajar yang cukup besar
- ALGOL, Lisp, ML, Self, Forth, APL, Prolog adalah klasifikasi inti, dan tiap keluarga memakai bahasa representatif sebagai sampel acuan untuk menilai garis keturunan bahasa lain
- ALGOL dicirikan oleh organisasi fungsi yang berpusat pada penugasan, pernyataan kondisional, dan perulangan; Lisp oleh makro dan kode berbentuk daftar; ML oleh fungsi kelas satu dan rekursi; Self oleh objek pengirim pesan; Forth oleh sintaks berbasis stack; APL oleh array n-dimensi; Prolog oleh fakta dan struktur pencarian
- Bagi semua programmer, kemahiran dalam bahasa keluarga ALGOL adalah prioritas, lalu belajar SQL, dan setelah itu terus mempelajari bahasa purwa yang asing akan lebih menguntungkan dalam jangka panjang
Tujuh Bahasa Purwa Pemrograman
- Saat memilih bahasa pemrograman, menguasai pola dasar lebih penting daripada perbedaan sintaks individual, dan di antara bahasa dalam keluarga yang mirip, struktur dasar seperti penelusuran array atau penelusuran kombinasi hampir selalu berbentuk sama
- Keluarga bahasa yang berbeda memiliki perbedaan besar dalam cara pengulangan, rekursi, dan penyusunan program, dan kumpulan pola dasar inilah yang membentuk bahasa-bahasa purwa yang berbeda
- Mempelajari bahasa baru yang berbagi bahasa purwa yang sudah akrab adalah perpindahan yang relatif mudah, tetapi berpindah ke bahasa purwa yang asing membutuhkan waktu yang besar dan jalur berpikir baru
- Bahasa purwa yang dikenali dalam bidang perangkat lunak ada tujuh: ALGOL, Lisp, ML, Self, Forth, APL, Prolog
- Tiap bahasa purwa diklasifikasikan dengan memakai bahasa representatif tertentu sebagai semacam sampel acuan, lalu bahasa lain dinilai garis keturunannya dengan membandingkannya dengan sampel itu
-
ALGOL
- Program tersusun sebagai urutan penugasan, pernyataan kondisional, dan perulangan, dan diorganisasikan dalam satuan fungsi
- Banyak bahasa menambahkan sistem modul, cara mendefinisikan tipe data baru, polimorfisme, serta struktur alur kontrol alternatif seperti exception atau coroutine
- Sebagian besar bahasa pemrograman yang digunakan luas saat ini termasuk dalam garis keturunan bahasa purwa ini
- ALGOL sendiri mencakup ALGOL 58, ALGOL 60, ALGOL W, ALGOL 68
- Assembly language, Fortran, C, C++, Python, Java, C#, Ruby, Pascal, JavaScript, dan Ada terhubung ke garis keturunan ini
- Ini adalah bahasa purwa tertua, dengan silsilah yang dapat ditelusuri hingga formalisasi program Ada Lovelace untuk mesin analitis Babbage
- Bahasa mesin dan assembly pada komputer berarsitektur Eckert-Mauchly yang berlanjut ke EDVAC dan Univac awal, serta upaya bahasa tingkat tinggi awal dari A-0 milik Grace Hopper hingga Fortran dan COBOL, semuanya mengambil bentuk ini
- Pada 1960-an, structured programming berkembang di dunia akademik dan membuat bahasa-bahasa ini lebih mudah dikelola; hasilnya adalah ALGOL 60, dan setelah itu sebagian besar anggota keluarga ini diturunkan darinya
- Seiring waktu ada kecenderungan untuk menyerap fitur dari bahasa purwa lain
- Pada 1980-an, konsep keluarga Self diadopsi dalam bentuk class dan dipakai sebagai sarana implementasi definisi tipe data serta polimorfisme
- Sejak 2010, konsep keluarga ML juga mulai muncul
-
Lisp
- Sintaks yang menggabungkan ekspresi prefiks berkurung dengan representasi list
(+ 2 3)
(defun square (x) (* x x))
(* (square 3) 3)
- Karena representasi list berupa item yang dipisahkan spasi dan dibungkus kurung tertanam di dalam bahasa, kode itu sendiri berbentuk list
- Makro dapat menerima list, memodifikasinya, lalu menyerahkan kode yang telah diubah ke compiler, sehingga programmer dapat mendefinisikan ulang makna bahasa
- Dalam sebagian besar penulisan kode, bahasa ini cenderung bekerja seperti bahasa purwa lain, biasanya ALGOL atau ML, tetapi sistem makro menjadi pembeda utamanya
- Sintaks
loop di Common Lisp juga bukan fitur bawaan bahasa, melainkan didefinisikan sebagai makro
- Ada banyak varian Lisp awal, tetapi komunitas akhirnya mencapai konsensus pada Common Lisp
- Sussman dan Steele menelusuri sejauh mana semuanya bisa dilakukan dengan fungsi, dan menghasilkan Scheme
- Ada Lisp untuk tujuan khusus seperti Lush untuk komputasi numerik, AutoLISP sebagai bahasa skrip AutoCAD, dan Emacs Lisp untuk mengimplementasikan perilaku editor Emacs
- Belakangan, Clojure muncul sebagai cabang besar ketiga dalam keluarga Lisp
- Muncul sekitar setahun setelah Fortran, dan merupakan keluarga bahasa tertua kedua yang masih digunakan sampai sekarang
- Titik awalnya adalah pertanyaan matematis tentang bagaimana menuliskan struktur matematika yang dapat mengevaluasi ekspresinya sendiri
- John McCarthy mengajukan jawabannya pada 1958, lalu itu diimplementasikan di komputer
- Lisp awal tidak cocok dengan mesin saat itu karena latar belakang matematisnya; masalah memori dan siklus CPU bukanlah topik dalam matematika, sehingga teknik seperti garbage collection menjadi perlu
- Pada akhir 1970-an dan awal 1980-an, ada mesin yang dirancang dari dasar hanya untuk menjalankan Lisp
- Banyak elemen integrated development environment modern ditemukan di mesin-mesin itu
- Pada masa yang sama, Lisp adalah alat utama penelitian kecerdasan buatan, dan ketika demam AI pada 1980-an gagal membuahkan hasil, Lisp ikut jatuh bersama bidang itu ke dalam AI Winter
- Namun Lisp tetap bertahan, dan dengan peningkatan kinerja komputer serta adopsi fiturnya oleh bahasa lain, kesulitan implementasinya kini berkurang
-
ML
- Fungsi adalah nilai kelas satu, dan bahasa ini memiliki sistem tipe keluarga Hindley-Milner yang dapat mengekspresikan beragam fungsi dan tagged union
- Semua pengulangan dilakukan melalui rekursi
sum [] = 0
sum (x:xs) = x + sum xs
- Digunakan pula pendekatan mendefinisikan fungsi yang mengenkapsulasi pola pengulangan, lalu menerima fungsi lain untuk mewujudkan perilakunya
map _ [] = []
map f (x:xs) = (f x) : (map f xs)
- Beberapa bahasa seperti Miranda dan Haskell memakai lazy evaluation secara default
- Bahasa lain memperluas sistem tipe ke berbagai arah
- OCaml mencoba menggabungkan konsep bahasa purwa Self
- Agda dan Idris mengadopsi sistem tipe dependen yang mencampurkan nilai dan tipe
- 1ML menggabungkan modul dan tipe
- Dari ML lahir CaML, Standard ML, OCaml
- Keluarga terkait seperti Miranda, Haskell, Agda, dan Idris juga berlanjut darinya
- ML awalnya adalah metalanguage untuk program pembuktian teorema yang dikembangkan di Cambridge, Inggris, dan namanya pun berasal dari sana
- Setelah itu ML menyebar sebagai bahasa mandiri di luar konteks tersebut, dan terutama populer di Eropa, khususnya Inggris dan Prancis
-
Self
- Program tersusun sebagai kumpulan objek yang saling mengirim pesan, dan semua perilaku diwujudkan dengan cara ini
- Objek baru dibuat dengan mengirim pesan ke objek yang sudah ada
- Pernyataan kondisional pun dijalankan lewat variabel yang merujuk ke salah satu dari objek true atau false
- Kedua objek itu menerima pesan dengan parameter fungsi yang dijalankan saat benar dan fungsi yang dijalankan saat salah
- Objek true mengeksekusi fungsi pertama, dan objek false mengeksekusi fungsi kedua
- Kode pemanggil tidak tahu itu objek yang mana, dan hanya mengirim pesan
- Perulangan juga bekerja dengan cara yang sama, dan dengan membuat objek yang tepat lalu menempatkannya di posisi yang tepat, seluruh makna bahasa dapat didefinisikan ulang
- Bahasa-bahasa seperti ini biasanya menyimpan source bukan sebagai file teks, melainkan di dalam lingkungan live
- Programmer memodifikasi sistem live, lalu menyimpan keadaannya alih-alih mengompilasi file untuk membangun sistem
- Contoh pentingnya adalah Smalltalk dan Self
- Banyak bahasa hanya mengadopsi sebagian dari cara pengiriman pesan keluarga ini, dan adopsi parsial seperti itu biasanya disebut pemrograman berorientasi objek
- Sebagian besar di antaranya berbasis Smalltalk, dan hanya JavaScript yang menjadi pengecualian karena berasal dari sistem objek tanpa class milik Self
- Sistem objek di Common Lisp menggeneralisasi pendekatan ini sehingga runtime memilih kode yang dijalankan berdasarkan semua parameter, bukan hanya satu objek penerima pesan
- Erlang mengubah arahnya: alih-alih alur eksekusi berpindah di antara objek, thread eksekusi paralel secara eksplisit mendengarkan dan mengirim pesan
- Bahasa aslinya adalah Smalltalk, yang dikembangkan di Xerox Parc pada akhir 1970-an dan 1980-an
- Pada 1980-an ada beberapa sistem Smalltalk komersial, dan IBM memakai Smalltalk untuk mengembangkan koleksi VisualAge, yaitu alat pemrograman untuk bahasa lain
- Saat ini Smalltalk terutama bertahan dalam bentuk open source Pharo Smalltalk
- Banyak riset dilakukan untuk menjalankan Smalltalk dengan cepat dan efisien, dan puncaknya adalah proyek Strongtalk
- Temuan dari Strongtalk punya arti historis karena menjadi dasar compiler JIT HotSpot milik Java
- Smalltalk mewarisi konsep nilai dan tipe dari bahasa sebelumnya lalu mengimplementasikan class; semua objek memiliki class yang memberinya tipe, dan class menciptakan objek bertipe itu
- Self menghapus konsep class dan hanya terdiri dari objek
- Karena dianggap bentuk yang lebih murni, Self dipilih sebagai sampel untuk bahasa purwa ini
-
Forth
- Bahasa stack merupakan semacam bayangan cermin Lisp, dan berbagi sintaks dengan kalkulator notasi Polandia terbalik milik Hewlett Packard
- Bahasa ini memiliki stack data; saat menulis literal seperti
42, nilainya didorong ke stack, dan nama fungsi bekerja atas stack tanpa parameter eksplisit
- Aritmetika sederhana pun berbentuk terbalik seperti
2 3 + 5 *
- Definisi fungsi juga sangat ringkas
- Pada kebanyakan varian Forth,
: menandai definisi kata baru
square berarti memanggil dup lalu *
dup menggandakan item teratas stack, dan * mengalikan dua item teratas
- Parser dapat dicegat dan diganti dengan kode sendiri, sehingga seluruh sintaks bisa diganti
- Umum dijumpai program Forth yang mendefinisikan bahasa kecil, seperti subset Fortran, layout paket, atau cara mem-parsing langsung diagram ASCII yang menyatakan transisi state machine
- Termasuk berbagai varian Forth, PostScript, Factor, dan Joy
- Joy adalah bahasa fungsional murni yang memakai formalisasi matematis komposisi alih-alih stack
- Forth pertama kali ditulis pada 1970 untuk mengendalikan teleskop radio
- Setelah itu menyebar luas ke seluruh dunia embedded system
- Sistem Forth cukup mudah di-bootstrap sehingga ada puluhan varian yang dibuat oleh banyak programmer untuk kebutuhan masing-masing
- PostScript muncul pada 1980-an sebagai sarana fleksibel untuk mendeskripsikan dokumen pada printer
- Dalam banyak hal PostScript lebih terbatas daripada Forth, tetapi ia mendefinisikan operasi dasar terkait layout grafis di dalam bahasa
-
APL
- Segala sesuatu dalam bahasa ini adalah array n-dimensi
- Operator terdiri dari satu atau dua simbol, dan melakukan operasi tingkat tinggi terhadap seluruh array
- Ekspresinya sangat padat, sehingga rangkaian simbol itu sendiri menjadi penanda operasi tanpa perlu diberi nama lain
- Sebagai contoh, menghitung rata-rata variabel
x ditulis sebagai (+⌿÷≢) x
- APL, J, K adalah contoh representatif
- Operasi tingkat tinggi atas array sebagian telah diekspor ke banyak lingkungan seperti MATLAB, NumPy, dan R
- APL bermula dari notasi matematika yang dibuat Kenneth Iverson pada 1960-an, lalu kemudian diimplementasikan di komputer
- Setelah itu bahasa ini terus mempertahankan basis pendukung di ceruk pengguna yang melakukan komputasi berat
- Bahasa turunannya, K, sangat populer di lingkungan finansial
-
Prolog
- Program tersusun sebagai kumpulan fakta
father(bob, ed).
father(bob, jane).
- Digunakan pula fakta tak terikat ke ground value yang menurunkan fakta dari fakta lain melalui variabel
grandfather(X, Y) :- father(X, Z), father(Z, Y).
- Runtime Prolog menerima fakta-fakta ini dan kueri, lalu melakukan pencarian untuk menemukan hasil
- Jika struktur definisi faktanya dipilih dengan tepat, kelengkapan Turing dapat tercapai
- Dalam Prolog, term yang membentuk fakta adalah tipe data khas tersendiri, yang dapat dibangun lalu diteruskan ke runtime
- Dalam hal ini posisinya mirip dengan makro di Lisp atau penggantian parser di Forth
- Karena program Prolog pada hakikatnya adalah pencarian, penyetelannya biasanya berpusat pada mengatur urutan pencarian dan memotong lebih awal jalur yang tidak menghasilkan, seperti pada kueri basis data
- Mencakup Prolog, Mercury, Kanren
- Sebagian besar pemrograman nyata dalam keluarga bahasa purwa ini terjadi di Prolog itu sendiri, dan komunitasnya sangat terpadu
- Pada 1970-an, para ahli logika di Prancis menyadari bahwa program dapat diekspresikan sebagai logika orde pertama, lalu mulai mencoba mengimplementasikannya
- Pada 1980-an, proyek komputer generasi kelima Jepang bertaruh besar pada Prolog, tetapi bersama kegagalan proyek itu reputasi Prolog juga merosot
- Terlepas dari itu, selama puluhan tahun riset terus dilakukan untuk membuat runtime Prolog efisien dalam kebanyakan kasus dan untuk menambahkan fitur baru
- Fitur seperti kendala numerik ditambahkan, yang mengarah ke constraint logic programming
- Prolog terus muncul di area-area ceruk
- Pengecekan tipe Java selama bertahun-tahun diimplementasikan dengan Prolog
- Alat pencarian source code awal Facebook juga berbasis Prolog
Bagaimana Memanfaatkannya
- Bagi kebanyakan programmer, sebagian atau seluruh keluarga bahasa ini mungkin terasa sangat asing, tetapi masing-masing layak diberi investasi waktu karena jalur berpikir dan kemungkinan baru yang dibukanya
- Dalam sudut pandang ALGOL, dua hal bisa tampak sepenuhnya berbeda, padahal dari sudut pandang lain perbandingannya justru sepele; bentuk seperti ini sangat sering terjadi
-
Prioritas
- Semua programmer perlu menguasai satu bahasa keluarga ALGOL dengan baik
- Setelah itu, disarankan mempelajari SQL, yaitu bahasa keluarga Prolog
- Dalam karier, manfaatnya berada di posisi terbesar kedua setelah ALGOL
-
Ekspansi selanjutnya
- Setelah menguasai dua keluarga di atas, dalam jangka panjang akan menguntungkan untuk mempelajari satu bahasa baru dari keluarga bahasa purwa yang asing setiap tahun
- Bahasa yang disarankan dari tiap keluarga dan urutannya adalah sebagai berikut
- Lisp: PLT Racket
- ML: Haskell
- Self: Self
- Prolog: Prolog
- Forth: gForth
- APL: K, digunakan melalui
ok
-
Penyesuaian urutan
- Jika banyak melakukan komputasi numerik, lebih cocok mempelajari K lebih awal
- Jika banyak melakukan pemrograman embedded, lebih cocok mempelajari gForth lebih awal
- Namun urutan itu sendiri maupun pilihan bahasa yang persis tidak terlalu penting
- Memilih Standard ML atau OCaml alih-alih Haskell, Common Lisp alih-alih PLT Racket, atau Factor alih-alih gForth juga tetap termasuk pilihan yang wajar
-
Pelengkap yang tercantum di catatan kaki
- Bahkan setelah mempelajari SQL, tetap perlu mempelajari Prolog itu sendiri
- Karena cara penggunaan nyatanya cukup berbeda dari SQL
- Ada pendapat pembaca bahwa untuk memahami Forth secara mendalam, pendekatan yang umum adalah membuat implementasi Forth sendiri
- Disebutkan bahwa Forth cukup kecil sehingga satu orang dapat mengimplementasikannya dari dasar dalam waktu yang relatif singkat
- gForth adalah implementasi yang baik untuk mempelajari ANS Forth
- Disebutkan FORTH Fundamentals, Volume 1 karya McCabe sebagai materi belajar
- Forth lain yang juga disebut untuk dilihat bersama adalah PygmyForth, eForth, colorForth
1 komentar
Komentar Hacker News
Di kelas PL di Tufts, kami pernah langsung membuat versi mini untuk masing-masing dari 4 keluarga bahasa awal, yaitu imperatif, Lisp, ML, dan Smalltalk, dan senang rasanya melihat proses itu kini juga terbit sebagai buku ajar. Agak disayangkan bagian Prolog yang dulu sempat ada sekarang hilang
Kalau ada satu hal yang ingin saya ubah dari klasifikasi tulisan ini, Ruby menurut saya jelas lebih tepat dilihat sebagai bahasa berorientasi objek daripada keluarga Algol. Pengaruh Smalltalk sangat besar, dan bahkan nama pustaka standarnya masih menyisakan jejak itu, misalnya memakai
collectalih-alihmap. Di Ruby, dari awal sampai akhir semuanya adalah objek, dan pemanggilan metode juga paling alami dipahami sebagai mengirim pesan ke objek. Memang sering dibandingkan dengan Python, tetapi jalur evolusinya cukup berbeda, dan sekarang rasanya keduanya bertemu di titik ekosistem yang mirip. Bagi saya, Ruby terasa seperti alpaka yang lebih hangat dibanding PythonHello Worldmungkin kurang terlihat, tetapi bahkan tipe dasar pun semuanya sudah menjadi objek. Untuk menekankan bahwa bahkan bilangan bulat adalah objek, cukup tunjukkantype(42)dandir(42)kepada orang yang tidak suka OOPSaya ingin menambahkan satu kategori lagi dalam silsilah bahasa, yaitu bahasa untuk mengekspresikan bukti. Ini adalah keluarga tempat program sekaligus menjadi bukti lewat korespondensi Curry-Howard, dan Lean adalah contoh utamanya. Memang bisa juga dilihat sebagai subkategori dari fungsional, tetapi karena tujuan utamanya adalah verifikasi, bukan eksekusi, rasanya layak dibahas sebagai sumbu tersendiri
Baru-baru ini saya meninjau lagi proyek perbandingan bahasa, berupa benchmark penguraian siklus permutasi bertanda paralel untuk 3.715.891.200 signed permutation dari 10 karakter. Saya ingin mencari bukan sekadar bahasa purwarupa, tetapi implementasi modern dari tiap paradigma yang sungguh layak dipilih untuk pemrograman riset. Saya menilai bukan hanya performa, tetapi juga kemudahan mendapat bantuan AI dan apakah saya nyaman membaca serta berpikir dengan kodenya, dan berkat AI saya bisa melakukan semacam wisata optimisasi yang cukup dalam untuk tiap bahasa. Hasilnya saya rangkum di sini, dan cukup mengejutkan bahwa F# muncul di posisi paling atas
Saya juga pernah menulis artikel serupa di sini. Saya setuju dengan Algol, Lisp, Forth, APL, dan Prolog, tetapi untuk bahasa fungsional inovatif saya memasukkan SASL yang sedikit lebih awal daripada ML, dan untuk perwakilan objek saya memilih Smalltalk yang muncul lebih dulu daripada Self. Saya juga menambahkan Fortran, COBOL, SNOBOL, dan Prograph karena menurut saya masing-masing mengubah permainan dengan caranya sendiri
Saya ingin menambahkan keluarga semantik ke diskusi ini. Misalnya Verilog, Petri nets, Kahn process networks, dataflow machines, process calculi, reactive, term rewriting, keluarga constraint solver/theorem prover, dan probabilistic programming. Selain itu ada juga bahasa seperti Unison, Darklang, temporal dataflow, dan DBSP yang tidak pas masuk 7 kategori lama, tetapi secara praktik sudah mendekati tahap produksi. Ini mungkin terdengar agak curang, tetapi kebanyakan memang merupakan model komputasi yang sejajar dengan model mesin von Neumann. Sudah lama saya ingin menulis sesuatu seperti “semua cara komputasi yang kita kenal, di luar von Neumann”
1+1ditulis ulang menjadi bentuk sepertiADD(1,1), saya bisa mem-parsing-nya dengan cara yang saya pahami. Ditambah lagi saya keras kepala menolak belajar regex, jadi kodenya jadi cukup aneh, dan saya masih ingat rekan tim berkata, “kalau Andy bilang bisa, jangan disentuh.” Orang lain di tim menyelesaikannya dengan regex dan kodenya kira-kira 20 kali lebih pendek daripada punya sayaMata kuliah “Concepts of programming languages” yang saya ambil di TU Delft adalah mata kuliah favorit saya selama kuliah ilmu komputer. Kami belajar C, sisi fungsional lewat Scala, dan konsep prototipe lewat JavaScript, dan itu sangat mempermudah saya saat beberapa tahun kemudian belajar Elixir. Ada juga kelas membuat agen Unreal Tournament dengan GOAL, bahasa berbasis Prolog. Lama sekali saya tidak pernah benar-benar paham Prolog cocok dipakai untuk apa, tetapi akhirnya saya memakainya untuk membuat spellcheck yang memaksa kalimat Papiamentu buruk hasil LLM diperbaiki berulang kali
Saya setuju dengan gagasan bahwa kita perlu belajar bahasa dari kategori yang berbeda-beda. Baru setelah belajar OCaml, fungsi benar-benar terasa seperti fungsi matematis bagi saya, dan Mathematica membentuk kebiasaan melihat ekspresi itu sendiri sebagai input. Notasi Polandia terbalik di PostScript memberi kesan seperti bukan sekadar aritmetika yang berbeda, tetapi benar-benar menyusun ulang cara berpikir saya. Namun saya tidak setuju dengan klaim bahwa memilih Java, C#, C++, Python, atau Ruby itu sama saja. Kalau targetnya hanya mengimplementasikan quicksort mungkin memang mirip, tetapi bagi orang yang benar-benar ingin membangun sesuatu, pilihan bahasa bisa membuat perbedaan sebesar siang dan malam. Kalau seseorang ingin membuat game 3D lalu pertama kali diberi Ruby, atau ingin melakukan data science eksploratif atau deep learning tetapi pertama kali diberi Java, motivasinya bisa langsung turun
Tulisan ini mengingatkan saya pada 7 languages in 7 weeks karya Bruce Tate. Saya juga pertama kali mengenal Erlang dari buku itu. Tetapi secara sejarah, memasukkan COBOL dan Fortran ke keluarga Algol terasa agak dipaksakan, meski tetap mengingatkan bahwa sejarah memang pada dasarnya selalu mengandung penyederhanaan
Ada juga diskusi HN lama yang terkait. Diskusi sebelumnya bisa membantu memahami konteks