Maksud dari pertanyaan saya bukanlah untuk memulai perang api, melainkan untuk menentukan dalam situasi apa setiap bahasa adalah "alat terbaik untuk pekerjaan itu".
Saya telah membaca beberapa buku tentang Clojure ( Programming Clojure , Practical Clojure , The Joy of Clojure , dan Manning Early Access edisi Clojure in Action ), dan menurut saya itu adalah bahasa yang fantastis. Saat ini saya membaca Let Over Lambda yang sebagian besar berhubungan dengan makro Common Lisp, dan, itu juga, merupakan bahasa yang sangat menarik.
Saya bukan ahli Lisp (lebih dari seorang pemula), tetapi keluarga bahasa ini membuat saya terpesona, seperti halnya pemrograman fungsional, pada umumnya.
Keuntungan dari Clojure (dan kerugian dari "orang lain"):
Berjalan di JVM.
JVM adalah lingkungan bahasa berperforma tinggi yang sangat stabil yang memenuhi impian Sun tentang "Menulis sekali, jalankan [hampir] di mana saja". Saya dapat menulis kode di Macbook Pro saya, mengkompilasinya menjadi file JAR yang dapat dieksekusi, dan kemudian menjalankannya di Linux dan Microsoft Windows dengan sedikit pengujian tambahan.
JVM (Hotspot, dan lainnya) mendukung pengumpulan sampah berkualitas tinggi serta kompilasi dan pengoptimalan just-in-time yang sangat baik. Dimana hanya beberapa tahun yang lalu, saya menulis semua yang harus berjalan cepat di C, sekarang saya tidak ragu melakukannya di Java.
Model standar, sederhana, multithreading. Apakah Common Lisp memiliki paket multithreading standar?
Hancurkan monoton dari semua tanda kurung itu dengan
[]
,,{}
dan#{}
, meskipun pakar Common Lisp mungkin akan memberi tahu saya bahwa dengan makro pembaca, Anda dapat menambahkannya ke CL.
Kerugian dari Clojure :
- Berjalan di JVM.
- Tidak ada rekursi atau kelanjutan ekor. Apakah Common Lisp mendukung kelanjutan? Skema membutuhkan dukungan untuk keduanya, saya yakin.
Keuntungan Orang Lain (Lisp Umum, khususnya) (dan kerugian Clojure):
Makro pembaca yang dapat ditentukan pengguna.
Keunggulan lainnya?
Pikiran? Perbedaan lainnya?
sumber
Jawaban:
Daftar pribadi saya alasan untuk memilih Clojure daripada Lisps lain (ps Saya masih berpikir semua Lisps bagus!):
Berjalan di JVM - karenanya mendapat akses otomatis ke teknik fantastis di JVM itu sendiri (algoritme pengumpulan sampah tingkat lanjut, pengoptimalan HotSpot JIT, dll.)
Interoperabilitas Java yang sangat baik - menyediakan kompatibilitas dengan sejumlah besar library di ekosistem bahasa Java / JVM. Saya telah menggunakan Clojure sebagai bahasa "perekat" untuk menghubungkan perpustakaan Java yang berbeda dengan efek yang bagus. Karena saya juga mengembangkan banyak kode Java, sangat membantu bagi saya bahwa Clojure terintegrasi dengan baik dengan tooling Java (misalnya saya menggunakan Maven, Eclipse dengan plugin Counterclockwise untuk pengembangan Clojure saya)
Sintaks yang bagus untuk vektor
[1 2 3]
, peta,{:bob 10, :jane 15}
dan set#{"a" "b" "c"}
- Saya menganggap alat yang cukup penting ini untuk pemrograman modern (selain daftar tentu saja!)Saya pribadi menyukai penggunaan tanda kurung siku untuk formulir penjilidan: misalnya
(defn foo [a b] (+ a b))
- Saya pikir itu membuat kode sedikit lebih jelas untuk dibaca.Penekanan pada pemrograman yang malas dan fungsional dengan struktur data yang persisten dan tidak dapat diubah - khususnya semua pustaka inti Clojure dirancang untuk mendukung ini secara default
Implementasi STM yang sangat baik untuk konkurensi multi-core. Saya yakin Clojure memiliki kisah konkurensi terbaik dari bahasa apa pun saat ini (lihat video ini untuk penjelasan lebih lanjut oleh Rich Hickey sendiri )
Ini adalah Lisp-1 (seperti Skema), yang secara pribadi saya lebih suka (menurut saya dalam bahasa fungsional, masuk akal untuk menyimpan fungsi dan data dalam namespace yang sama)
sumber
Perlu diingat bahwa Clojure adalah bahasa dan implementasi (biasanya di JVM). Common Lisp adalah bahasa dengan lebih dari sepuluh implementasi berbeda. Jadi kami memiliki ketidakcocokan kategori di sini. Anda dapat misalnya membandingkan Clojure dengan SBCL.
Umumnya:
versi Common Lisp berjalan di JVM: ABCL
kebanyakan implementasi Lisp Umum lainnya tidak
sebagian besar implementasi CL memiliki kemampuan multitasking, perpustakaan menyediakan antarmuka yang umum
Lisp umum memiliki sintaks untuk array. Sintaks untuk tipe data lain dapat ditulis oleh pengguna dan disediakan oleh berbagai pustaka.
Common Lisp tidak mendukung pengoptimalan atau kelanjutan panggilan ekor. Implementasi menyediakan TCO dan perpustakaan menyediakan beberapa bentuk kelanjutan.
sumber
Perbedaan penting antara Clojure dan Common Lisp adalah bahwa Clojure lebih bersifat preskriptif tentang pemrograman fungsional. Filsafat Clojure, idiom, dan sampai taraf tertentu bahasa / perpustakaan sangat mendorong dan kadang-kadang bersikeras bahwa Anda memprogram secara fungsional (tanpa efek samping, tidak ada keadaan yang bisa berubah).
Common Lisp pasti mendukung pemrograman fungsional, tetapi juga memungkinkan status yang bisa berubah dan pemrograman imperatif.
Tentu saja, ada sejumlah manfaat untuk pemrograman fungsional, di bidang konkurensi dan lainnya. Tetapi semua hal lainnya sama, ada baiknya juga untuk memiliki pilihan pendekatan mana yang ingin Anda gunakan untuk setiap situasi. Clojure tidak sepenuhnya melarang pemrograman imperatif, tetapi kurang mengakomodasi gaya itu daripada Common Lisp.
sumber
Berikut adalah video yang bagus dengan perbandingan Scheme (Racket kebanyakan) dan Clojure .
Agar adil, Racket memiliki gula sintaks (barang pembaca tambahan) untuk tipe data juga (#hash, #, tanda kurung siku, dll.)
Plus, satu-satunya cara Clojure untuk membuat panggilan ekor yang tepat adalah dengan menggunakan
recur
, itulah sisi negatif dari kompilasi ke JVM.sumber
trampoline
untuk panggilan ekor.