Saya seorang pemula yang lengkap dengan OCaml. Baru-baru ini saya menemukan halaman ini dengan daftar sejumlah kritik terhadap OCaml.
Melihat bahwa halaman itu sudah cukup tua (2007): manakah dari poin-poin yang tercantum yang masih benar hingga hari ini? Misalnya: apakah masih benar bahwa tidak mungkin untuk mencetak objek generik?
Saya ingin menjelaskan bahwa saya tidak mencari diskusi tentang pendapat yang diungkapkan di dalamnya. Saya bertanya apakah informasi yang tercantum, seperti fakta bahwa integer overflow tanpa peringatan, masih benar untuk versi OCaml yang lebih baru
Jawaban:
Artikel ini dibahas di beberapa tempat:
Untuk meringkas: ya, OCaml bukan Lisp, dan tidak, itu tidak sempurna (apa artinya itu?). Saya tidak berpikir poin yang disebutkan dalam posting blog relevan untuk programmer O'Caml sehari-hari.
Setelah mempelajari O'Caml, saya pikir itu adalah bahasa yang menarik yang dapat membantu Anda membangun program yang bahkan tidak berani Anda tulis, katakanlah, C / C ++ / Java: misalnya, lihat Frama-C .
Untuk deskripsi terbaru O'Caml, saya mendorong Anda untuk membaca tentang fitur-fiturnya : bahasa ini mempromosikan teknik pemeriksaan tipe statis yang kuat yang memungkinkan implementasi untuk fokus pada menghasilkan runtime yang performant, namun aman.
Penting : Saya bukan ahli OCaml: jika Anda salah satu dari mereka dan melihat saya menulis sesuatu yang sangat salah, mohon perbaiki saya. Saya akan mengedit posting ini sesuai.
Pengecekan tipe statis
Rasa Keamanan Palsu
Ini benar, tetapi jelas.
Pengetikan statis memberi Anda bukti yang dapat Anda percayai tentang subset properti program Anda. Kecuali Anda menerima semua formal, program rata-rata (non-mainan) akan dikenakan bug kesalahan pemrograman yang hanya dapat disaksikan saat runtime.
Saat itulah teknik pemeriksaan dinamis dapat diterapkan: kompiler OCaml memiliki tanda untuk menghasilkan file yang dapat dieksekusi dengan informasi debug, dan seterusnya ... Atau, ia dapat menghasilkan kode yang secara membabi buta mempercayai programmer dan menghapus informasi jenis sebanyak mungkin. Programmer yang menginginkan program yang kuat harus mengimplementasikan pemeriksaan dinamis secara eksplisit.
Hal yang sama berlaku untuk misalnya Common Lisp, tetapi terbalik: tipe dinamis pertama, dengan deklarasi tipe opsional dan arahan kompilator kedua.
Beberapa Tipe Dasar
Masih berlaku: bahasa inti tidak berubah (atau tidak secara dramatis).
Overflow Integer Diam
Ini adalah norma di sebagian besar bahasa bahwa integer overflow diperiksa dengan tangan. Saya tidak tahu ada perpustakaan yang akan mengetik-periksa operasi untuk memverifikasi apakah overflow dapat terjadi.
Modul Ketidakmampuan
Penulis menyebutkan Functors tetapi saya gagal melihat bagaimana contohnya tidak dapat diimplementasikan. Membaca bab Modul Kelas Pertama https://realworldocaml.org , tampaknya modul dapat digunakan untuk membuat dan membangun modul baru. Tentu saja, memodifikasi modul yang ada memerlukan modifikasi kode sumber, tetapi sekali lagi, ini tidak biasa di antara bahasa pemrograman.
"Secara semantik , fungsi dikompilasi INLINE"
Utas reddit di atas tidak setuju, mengatakan bahwa pengikatan diselesaikan pada waktu tautan. Namun, ini adalah detail implementasi dan saya pikir Semantically yang ditekankan berkaitan dengan cara fungsi diselesaikan. Contoh:
Program di atas mengkompilasi, dan ketika dieksekusi, mengembalikan 5, karena
g
didefinisikan dengan versi pertamaf
, sama seperti jika fungsi panggilang
inline panggilan kef
. Ini bukan "buruk", omong-omong, itu hanya konsisten dengan aturan bayangan nama O'Caml.Untuk meringkas : ya, modul tidak dapat diubah . Tetapi mereka juga komposer .
Polimorfisme Menyebabkan Kesalahan Tipe Run-time
Saya tidak dapat mereproduksi kesalahan yang disebutkan. Saya menduga itu adalah kesalahan kompiler.
Tidak ada makro
Memang, tidak ada makro selain preprosesor (OcamlP4, OcamlP5, ...).
Wrappers (dengan-file terbuka)
Mengetahui bagaimana UNWIND-PROTECT dapat berguna, ini memang menyakitkan untuk melihatnya absen dari lebih banyak bahasa. Berikut ini beberapa opsi:
Tempat
Saya tidak berpikir referensi umum ada di OCaml.
Kesuksesan Bahasa Minor
Rekam neraka penamaan bidang
Benar, tetapi Anda harus menggunakan modul:
Sintaksis
Masih berlaku (tapi sungguh, ini hanya sintaks).
Tidak Ada Polimorfisme
Masih berlaku, tapi entah bagaimana ada orang yang lebih suka itu daripada menara numerik Lisp (saya tidak tahu mengapa). Saya kira ini membantu dengan jenis inferensi.
Set fungsi yang tidak konsisten
Lihat proyek Termasuk Baterai OCaml . Secara khusus, BatArray , untuk contoh
map2
array.Tidak ada variabel dinamis
Dapat diimplementasikan:
Opsional ~ menghisap argumen
Dengan pembatasan bahasa, Anda tidak dapat mencampur argumen opsional dan kata kunci dalam Common Lisp. Apakah ini berarti itu menyebalkan? (tentu saja, ini dapat diubah dengan makro (lihat misalnya jawaban saya )). Lihat dokumentasi O'Caml untuk argumen opsional dan bernama dalam O'Caml.
Inkonsistensi aplikasi argumen parsial
Saya tidak berpikir ini benar-benar menjengkelkan dalam praktek.
Keterbacaan Aritmatika
Itu berlaku, tetapi Anda dapat menggunakan R atau Python untuk masalah numerik jika Anda mau.
Resolusi konflik nama diam
Masih berlaku, tetapi perhatikan bahwa ini didokumentasikan dengan baik.
Tidak ada input / output objek
Masih berlaku.
Implementasi, perpustakaan
Ini terus berubah setiap hari: tidak ada jawaban pasti.
Akhirnya,
... masih berlaku.
sumber
Rasa Keamanan Palsu . Ini tidak masuk akal.
Beberapa Tipe Dasar . OCaml sekarang memiliki byte dan byte array tetapi tidak ada string unicode bawaan, integer 16-bit, integer unsigned, float 32-bit, vektor atau matriks. Perpustakaan pihak ketiga menyediakan beberapa di antaranya.
Overflow Integer Diam . Tidak berubah tetapi itu tidak pernah menjadi masalah.
Modul Ketidakmampuan . Rekomendasinya bahwa fungsi dan modul harus bisa berubah adalah kemunduran suram untuk Lisp dan ide yang sangat buruk. Anda dapat menggantikan modul menggunakan
include
jika Anda mau, tetapi Anda tidak dapat memutasinya, tentu saja.Polimorfisme Menyebabkan Kesalahan Tipe Run-time . Ini adalah masalah besar dengan OCaml dan belum diperbaiki. Saat tipe Anda mengembangkan kesetaraan polimorfik, perbandingan dan hashing akan mulai gagal ketika mereka menemukan tipe seperti fungsi dan men-debug masalahnya sangat sulit. F # memiliki solusi hebat untuk masalah ini.
Tidak ada Macro . Ironisnya, ketika dia menulis OCaml ini sebenarnya memiliki dukungan penuh untuk makro tetapi mereka sekarang telah memutuskan untuk mengeluarkan fitur ini.
Pembungkus . Ini adalah masalah nyata dan belum diperbaiki. Masih belum ada
try ... finally
konstruk dalam bahasa OCaml dan tidak ada wrapper yang mengimplementasikannya di stdlib.Tempat . Tidak berubah tetapi tidak menjadi masalah.
Rekam neraka penamaan bidang . Struktur kode Anda dengan benar menggunakan modul.
Sintaks . Tidak berubah tetapi tidak menjadi masalah.
Tidak Ada Polimorfisme . Ini sebagian besar omong kosong ketika dia menulisnya dan tidak ada yang berubah.
Set fungsi yang tidak konsisten . OCaml masih tidak memiliki
cons
fungsi. Tidak apa-apa. Saya tidak ingin hal-hal Lisp dalam bahasa saya, terima kasih.Tidak ada variabel dinamis . Adalah hal yang baik tentang OCaml. Masih bagus tentang OCaml.
Opsional ~ menghisap argumen . Argumen opsional mengguncang. Saya mendesak Microsoft untuk meminta mereka menambahkan argumen opsional ke F #.
Inkonsistensi aplikasi argumen parsial . Eh?
Keterbacaan Aritmatika . Ini telah berubah sejak saya berhenti menggunakan OCaml ~ 8 tahun yang lalu. Ternyata sekarang bisa Anda lakukan
Int64.((q * n - s * s) / (n - 1L))
.Resolusi konflik nama diam . Dia mencoba melakukan pengembangan perangkat lunak penuh di REPL seperti yang Anda lakukan di Lisp. Jangan lakukan itu di OCaml. Gunakan file dan kompilasi batch yang beralih ke REPL hanya untuk pengujian, menjalankan kode sekali pakai, dan komputasi teknis interaktif.
Urutan evaluasi . Ini salah ketika dia menulisnya. Urutan evaluasi tidak ditentukan dalam OCaml.
Tidak ada input / output objek . Dia mengutip perpustakaan pihak ketiga yang sudah memecahkan "masalah" ini.
Compiler berhenti setelah kesalahan pertama . Eh?
Tidak ada jejak stack untuk executable yang dikompilasi secara asli . Tetap.
Debugger menyebalkan . Saya tidak pernah menggunakan debugger. Pengecekan tipe statis menangkap hampir semua bug saya.
GC menyebalkan . Saya menemukan GC OCaml luar biasa kecuali untuk satu masalah utama: kunci global mencegah pemrograman paralel.
Tidak ada deklarasi maju tersirat . Rekursi timbal balik secara eksplisit dirancang oleh semua ML. Satu-satunya keanehan adalah bahwa
type
definisi bersifat rekursif secara default sedangkanlet
binding adalah non-rekursif secara default.Fungsi putaran tidak ada . OCaml masih memiliki stdlib, tetapi perpustakaan pihak ketiga seperti Jane St's Core menyediakan
round
dan teman-teman.Daftar .
List.map
masih belum ekor rekursif. Saya mengirimkan tambalan untuk memperbaiki bug serius seperti ini dan harus menunggu bertahun-tahun sebelum muncul dalam rilis. Daftar masih tetap, tentu saja. Dan memang seharusnya begitu.Kecepatan . Saya percaya waktu kompilasi untuk varian polimorfik besar telah diperbaiki.
Pencocokan pola . Kemenangan harapan atas kenyataan. Komunitas Lisp gagal melakukan ini. Oleh karena itu aturan ke-10 saya: program Lisp yang cukup rumit berisi implementasi ad-hoc, yang ditentukan secara tidak resmi dan dipenuhi bug dari setengah dari kompiler pencocokan pola OCaml.
Ketika dia menulis bahwa Anda tidak bisa begitu saja melakukannya:
tetapi Anda bisa memanggil printer cantik dari tingkat atas sebagai panggilan perpustakaan, memberikannya informasi jenis yang diperlukan. Dan ada makro yang dapat Anda gunakan untuk membubuhi keterangan struktur data agar printer cantik dibuat otomatis.
sumber
cons
memberikan nada yang buruk (artikel asli adalah kata-kata kasar, tetapi Anda tidak perlu menyalinnya dari itu).+
int, float dan complexes tetapi Anda juga dapat mendefinisikan tipe Anda sendiri dan menambahkan kelebihan untuk+
mengerjakan tipe Anda. Ini memberikan singkat dan mudah dibaca Lisp atau Haskell dengan kinerja SML atau OCaml yang dapat diprediksi baik, mencapai sesuatu yang tidak dilakukan oleh bahasa lain.