Saya telah memikirkan pertanyaan ini sangat lama, tetapi benar-benar tidak dapat menemukan jawabannya di Google serta pertanyaan serupa di Stackoverflow. Jika ada duplikatnya, saya minta maaf untuk itu.
Banyak orang tampaknya mengatakan bahwa menulis kompiler dan alat bahasa lain dalam bahasa fungsional seperti OCaml dan Haskell jauh lebih efisien dan lebih mudah daripada menulisnya dalam bahasa imperatif.
Apakah ini benar? Dan jika demikian - mengapa begitu efisien dan mudah untuk menulisnya dalam bahasa fungsional daripada dalam bahasa imperatif, seperti C? Juga - bukankah alat bahasa dalam bahasa fungsional lebih lambat dari pada beberapa bahasa tingkat rendah seperti C?
Jawaban:
Seringkali kompiler banyak bekerja dengan pohon. Kode sumber diurai menjadi pohon sintaks. Pohon itu kemudian dapat diubah menjadi pohon lain dengan anotasi tipe untuk melakukan pemeriksaan tipe. Sekarang Anda dapat mengubah pohon itu menjadi pohon yang hanya berisi elemen bahasa inti (mengubah notasi sintaksis seperti gula ke dalam bentuk yang tidak berbatu). Sekarang Anda dapat melakukan berbagai pengoptimalan yang pada dasarnya adalah transformasi di pohon. Setelah itu Anda mungkin akan membuat pohon dalam beberapa bentuk normal dan kemudian mengulangi pohon itu untuk membuat kode target (perakitan).
Bahasa fungsional memiliki fitur seperti pencocokan pola dan dukungan yang baik untuk rekursi yang efisien, yang membuatnya mudah untuk bekerja dengan pohon, jadi itulah mengapa mereka umumnya dianggap sebagai bahasa yang baik untuk menulis kompiler.
sumber
Banyak tugas kompilator yang mencocokkan pola pada struktur pohon.
Baik OCaml dan Haskell memiliki kemampuan pencocokan pola yang kuat dan ringkas.
Lebih sulit menambahkan pencocokan pola ke bahasa imperatif karena nilai apa pun yang sedang dievaluasi atau diekstraksi untuk mencocokkan pola harus bebas efek samping.
sumber
Salah satu faktor penting untuk dipertimbangkan adalah bahwa sebagian besar proyek kompilator adalah ketika Anda dapat menghosting kompiler sendiri dan "memakan makanan anjing Anda sendiri". Untuk alasan ini ketika Anda melihat bahasa seperti OCaml di mana mereka dirancang untuk penelitian bahasa, mereka cenderung memiliki fitur yang bagus untuk masalah tipe kompilator.
Dalam pekerjaan compiler-esque terakhir saya, kami menggunakan OCaml untuk alasan ini persis saat memanipulasi kode C, itu hanya alat terbaik untuk tugas itu. Jika orang-orang di INRIA telah membangun OCaml dengan prioritas yang berbeda, itu mungkin tidak cocok.
Meskipun demikian, bahasa fungsional adalah alat terbaik untuk memecahkan masalah apa pun, jadi secara logis dapat dikatakan bahwa bahasa fungsional adalah alat terbaik untuk memecahkan masalah khusus ini. QED.
/ me: merangkak kembali ke tugas Java saya sedikit kurang menyenangkan ...
sumber
Pada dasarnya, kompiler adalah transformasi dari satu set kode ke kode lainnya - dari sumber ke IR, dari IR ke IR yang dioptimalkan, dari IR ke assembly, dll. Inilah tepatnya bahasa fungsional yang dirancang untuk - fungsi murni adalah hanya sebuah transformasi dari satu hal ke hal lainnya. Fungsi imperatif tidak memiliki kualitas ini. Meskipun Anda dapat menulis kode semacam ini dalam bahasa imperatif, bahasa fungsional dikhususkan untuk itu.
sumber
Lihat juga
F # pola desain
FP mengelompokkan berbagai hal 'berdasarkan operasi', sedangkan OO mengelompokkan hal-hal 'menurut jenis', dan 'menurut operasi' lebih alami untuk kompiler / juru bahasa.
sumber
Salah satu kemungkinannya adalah kompilator cenderung harus menangani dengan sangat hati-hati sejumlah kasus sudut. Mendapatkan kode yang benar sering kali menjadi lebih mudah dengan menggunakan pola desain yang menyusun implementasi dengan cara yang paralel dengan aturan yang diimplementasikannya. Seringkali yang berakhir menjadi deklaratif (pencocokan pola, "di mana") daripada desain imperatif (pengurutan, "ketika") dan dengan demikian lebih mudah untuk diterapkan dalam bahasa deklaratif (dan sebagian besar berfungsi).
sumber
Sepertinya semua orang melewatkan alasan penting lainnya. Sangat mudah untuk menulis bahasa khusus domain tertanam (EDSL) untuk parser yang sangat mirip (E) BNF dalam kode normal. Kombinator pengurai seperti Parsec cukup mudah untuk menulis dalam bahasa fungsional menggunakan fungsi tingkat tinggi dan komposisi fungsi. Tidak hanya lebih mudah tetapi juga sangat elegan.
Pada dasarnya Anda mewakili parser generik paling sederhana hanya sebagai fungsi dan Anda memiliki operasi khusus (biasanya fungsi orde tinggi) yang memungkinkan Anda menyusun parser primitif ini menjadi parser yang lebih rumit dan lebih spesifik untuk tata bahasa Anda.
Ini bukan satu-satunya cara untuk melakukan kerangka kerja pengupas tentunya.
sumber