Skema vs Common Lisp: Karakteristik apa yang membuat perbedaan dalam proyek Anda? [Tutup]

155

Tidak ada kekurangan pertanyaan "Skema vs Common Lisp" yang tidak jelas di StackOverflow dan di situs ini, jadi saya ingin membuat yang satu ini lebih fokus. Pertanyaannya adalah untuk orang yang memiliki kode dalam kedua bahasa:

Saat melakukan coding dalam Skema, elemen spesifik apa dari pengalaman coding Common Lisp Anda yang paling Anda lewatkan? Atau, sebaliknya, saat melakukan koding di Common Lisp, apa yang Anda lewatkan dari pengkodean di Skema?

Maksud saya bukan hanya fitur bahasa. Berikut ini adalah semua hal yang valid untuk dilewatkan, sejauh menyangkut pertanyaan:

  • Perpustakaan tertentu.
  • Fitur spesifik dari lingkungan pengembangan seperti SLIME, DrRacket, dll.
  • Fitur implementasi tertentu, seperti kemampuan Gambit untuk menulis blok kode C langsung ke sumber Skema Anda.
  • Dan tentu saja, fitur bahasa.

Contoh jenis jawaban yang saya harapkan:

  • "Aku sedang mencoba menerapkan X di Common Lisp, dan jika aku memiliki kelanjutan kelas satu Skema, aku benar-benar hanya akan melakukan Y, tetapi sebaliknya aku harus melakukan Z, yang lebih menyebalkan."
  • "Membuat skrip proses pembangunan dalam proyek Skema saya menjadi semakin menyakitkan ketika pohon sumber saya tumbuh dan saya terhubung di perpustakaan C. semakin banyak. Untuk proyek berikutnya, saya pindah kembali ke Common Lisp."
  • "Saya memiliki basis kode C ++ besar yang sudah ada, dan bagi saya, dapat menyematkan panggilan C ++ secara langsung dalam kode Skema Gambit saya benar-benar bernilai segala kekurangan yang mungkin dimiliki Skema vs Common Lisp, bahkan termasuk kurangnya dukungan SWIG."

Jadi, saya berharap cerita perang, daripada sentimen umum seperti "Skema adalah bahasa yang lebih sederhana" dll.

SuperElectric
sumber
25
Sebuah pertanyaan yang sangat bagus dan baik. Saya ingin tahu tentang ini sendiri; semoga ada beberapa orang di luar sana dengan keahlian dalam kedua bahasa yang bersedia memberikan wawasan.
Robert Harvey
1
@ Josh K - jelas dapat dijawab, tetapi belum tentu ada satu jawaban pasti. Kecuali saya bertaruh akan ada satu karena seseorang akan keluar dengan jawaban yang sangat mengagumkan sehingga semua orang seperti whoa!
glenatron
4
@Josh: Maka mungkin Anda tidak terbiasa dengan Skema dan Common Lisp Kedua bahasa sangat kuat dalam hak mereka sendiri, namun keduanya tidak memiliki penerimaan umum. Kenapa ini? Bisa jadi karena ada begitu banyak dialek; Mana yang Anda pilih? Perbandingan semacam ini bisa sangat mencerahkan, dan OP telah dengan hati-hati mengatakan pertanyaan untuk membatasi ruang lingkup jawaban yang, dalam pandangan saya, sangat spesifik dan dapat dijawab.
Robert Harvey
13
Teman-teman, jangan tutup pertanyaan hanya karena Anda tidak suka atau tidak bisa mengaitkannya. Ini jelas pertanyaan "nyata"; jika Anda tidak dapat menemukan alasan yang lebih baik untuk menutupnya, Anda tidak boleh memilih untuk menutup.
Robert Harvey
4
Anda dapat mengirim email ke Richard Stallman untuk jawabannya.
wassimans

Jawaban:

100

Gelar sarjana saya adalah Ilmu Kognitif dan Kecerdasan Buatan. Dari situ saya punya intro satu arah ke Lisp. Saya pikir bahasanya menarik (seperti dalam "elegan") tetapi tidak terlalu memikirkannya sampai saya menemukan Peraturan Kesepuluh Greenspun jauh kemudian:

Setiap program C atau Fortran yang cukup rumit berisi implementasi ad hoc, dispesifikasikan secara informal, ditanggulangi, lambat dari separuh Common Lisp.

Poin Greenspun adalah (sebagian) bahwa banyak program kompleks memiliki penafsir bawaan. Daripada membangun penerjemah menjadi bahasa yang ia sarankan, mungkin lebih masuk akal untuk menggunakan bahasa seperti Lisp yang sudah memiliki interpreter (atau kompiler) bawaan.

Pada saat itu saya sedang mengerjakan aplikasi yang agak besar yang melakukan perhitungan yang ditentukan pengguna menggunakan penerjemah khusus untuk bahasa khusus. Saya memutuskan untuk mencoba menulis kembali intinya di Lisp sebagai percobaan skala besar.

Butuh sekitar enam minggu. Kode asli adalah ~ 100.000 baris Delphi (varian Pascal). Di Lisp dikurangi menjadi ~ 10.000 baris. Yang lebih mengejutkan adalah fakta bahwa mesin Lisp 3-6 kali lebih cepat. Dan perlu diingat bahwa ini adalah karya seorang Lisp neophyte! Seluruh pengalaman itu cukup membuka mata saya; untuk pertama kalinya saya melihat kemungkinan menggabungkan kinerja dan ekspresif dalam satu bahasa.

Beberapa waktu kemudian ketika saya mulai mengerjakan proyek berbasis web saya mengikuti audisi sejumlah bahasa. Saya memasukkan Lisp dan Skema ke dalam campuran. Pada akhirnya saya memilih implementasi Skema-- Skema Chez . Saya sangat senang dengan hasilnya.

Proyek berbasis web adalah "mesin seleksi" berkinerja tinggi . Kami menggunakan Skema dalam sejumlah cara berbeda, mulai dari pemrosesan data hingga permintaan data hingga pembuatan halaman. Di banyak tempat kami sebenarnya memulai dengan bahasa yang berbeda tetapi akhirnya bermigrasi ke Skema karena alasan yang akan saya jelaskan secara singkat di bawah ini.

Sekarang saya dapat menjawab pertanyaan Anda (setidaknya sebagian).

Selama audisi kami melihat berbagai implementasi Lisp dan Skema. Di sisi Lisp kami melihat (saya percaya) Allegro CL, CMUCL, SBCL dan LispWorks. Di sisi Skema kami melihat (saya percaya) Bigloo, Chicken, Chez, Gambit. (Pemilihan bahasa sudah lama sekali; itu sebabnya saya agak kabur. Saya bisa menggali beberapa catatan jika itu penting.)

Langsung dari kelelawar kami sedang mencari a) utas asli dan b) dukungan Linux, Mac dan Windows. Gabungan kedua kondisi tersebut membuat semua orang tertekan, tetapi (saya pikir) Allegro dan Chez keluar - jadi untuk melanjutkan evaluasi kami harus melonggarkan persyaratan multi-threading.

Kami mengumpulkan serangkaian program kecil dan menggunakannya untuk evaluasi dan pengujian. Itu mengungkapkan sejumlah masalah. Sebagai contoh: beberapa implementasi memiliki cacat yang mencegah beberapa tes dari berjalan sampai selesai; beberapa implementasi tidak dapat mengkompilasi kode pada saat run-time; beberapa implementasi tidak dapat dengan mudah mengintegrasikan kode kompilasi run-time dengan kode pra-kompilasi; beberapa implementasi memiliki pemulung yang jelas lebih baik (atau jelas lebih buruk) daripada yang lain; dll.

Untuk kebutuhan kami, hanya tiga implementasi komersial - Allegro, Chez dan Lispworks - yang lulus tes utama kami. Dari ketiganya hanya Chez yang lulus semua tes dengan warna terbang. Pada saat itu saya pikir Lispworks tidak memiliki utas asli pada platform apa pun (saya pikir mereka lakukan sekarang) dan saya pikir Allegro hanya memiliki utas asli pada beberapa platform. Selain itu, Allegro memiliki biaya lisensi run-time "hubungi kami" yang sangat saya sukai. Saya percaya Lispworks tidak memiliki biaya run-time dan Chez memiliki pengaturan langsung (dan sangat masuk akal) (dan itu hanya menendang jika Anda menggunakan kompiler saat run-time).

Setelah menghasilkan potongan kode yang agak signifikan di Lisp dan Scheme, berikut adalah beberapa titik perbandingan dan kontras:

  • Lingkungan Lisp jauh lebih matang. Anda mendapatkan banyak bang untuk uang. (Karena itu, lebih banyak kode juga sama dengan lebih banyak bug.)

  • Lingkungan Lisp jauh lebih sulit untuk dipelajari. Anda membutuhkan lebih banyak waktu untuk menjadi mahir; Common Lisp adalah bahasa yang sangat besar - dan itu sebelum Anda sampai ke perpustakaan yang ditambahkan implementasi komersial di atasnya. (Karena itu, kasus sintaksis Skema jauh lebih halus dan rumit daripada hal apa pun di Lisp.)

  • Lingkungan Lisp bisa jadi agak lebih sulit untuk menghasilkan binari. Anda perlu "mengguncang" gambar Anda untuk menghapus bit yang tidak dibutuhkan, dan jika Anda tidak menjalankan program dengan benar selama proses itu, Anda bisa berakhir dengan kesalahan run-time nanti. . Sebaliknya, dengan Chez kami mengkompilasi file tingkat atas yang mencakup semua file lain yang dibutuhkan dan kami selesai.

Saya katakan sebelumnya bahwa kami akhirnya menggunakan Skema di sejumlah tempat yang pada awalnya tidak kami maksudkan. Mengapa? Saya dapat memikirkan tiga alasan dari atas kepala saya.

Pertama, kami belajar untuk mempercayai Chez (dan pengembangnya, Cadence). Kami banyak bertanya dari alat, dan itu disampaikan secara konsisten. Sebagai contoh, Chez secara historis memiliki sejumlah kecil cacat, dan manajer memorinya sangat, sangat baik.

Kedua, kami belajar untuk mencintai kinerja yang kami dapatkan dari Chez. Kami menggunakan sesuatu yang terasa seperti bahasa scripting - dan kami mendapatkan kecepatan kode asli dari itu. Untuk beberapa hal yang tidak masalah - tetapi tidak pernah sakit, dan kadang-kadang itu banyak membantu.

Ketiga, kami belajar untuk mencintai Skema abstraksi yang bisa diberikan. Ngomong-ngomong, saya tidak hanya bermaksud makro; Maksud saya hal-hal seperti penutupan, lambda, panggilan ekor, dll. Begitu Anda mulai berpikir dalam istilah-istilah itu, bahasa lain tampaknya agak terbatas dengan perbandingan.

Apakah Skema sempurna? Tidak; itu adalah trade-off. Pertama, ini memungkinkan masing-masing pengembang menjadi lebih efektif - tetapi lebih sulit bagi pengembang untuk saling memahami kode masing-masing karena rambu-rambu yang dimiliki sebagian besar bahasa (misalnya untuk loop) tidak ada dalam Skema (misalnya, ada sejuta cara untuk melakukan a for loop). Kedua, ada sekelompok pengembang yang jauh lebih kecil untuk diajak bicara, disewa, dipinjam, dll.

Singkatnya, saya pikir saya akan mengatakan: Lisp dan Skema menawarkan beberapa kemampuan yang tidak tersedia secara luas di tempat lain. Kemampuan itu adalah trade-off, jadi sebaiknya itu yang masuk akal dalam kasus khusus Anda. Dalam kasus kami, faktor-faktor penentu antara apakah akan menggunakan Lisp atau Skema lebih terkait dengan fitur-fitur yang sangat mendasar (dukungan platform, utas platform, kompilasi run-time, lisensi run-time) dibandingkan dengan fitur-fitur bahasa atau perpustakaan. Sekali lagi, dalam kasus kami itu juga merupakan trade-off: dengan Chez kami mendapatkan fitur inti yang kami inginkan tetapi kami kehilangan perpustakaan luas yang dimiliki lingkungan Lisp komersial.

Juga, hanya untuk mengulangi: kami telah melihat berbagai Lisps dan Skema sejak lama; mereka semua telah berevolusi dan membaik sejak saat itu.

Michael Lenaghan
sumber
1
Wow, itu pasti kode Delphi yang benar-benar mengerikan jika entah bagaimana berhasil melakukan 3-6x lebih lambat daripada implementasi Lisp! :(
Mason Wheeler
2
+1: Hal yang paling menarik tentang pos ini adalah kenyataan bahwa Anda beralih dari Lisp ke Skema setelah menyelesaikan proyek besar di Lisp. (Atau mungkin saya terlalu lama mengintai comp.lang.lisp.)
Larry Coleman
25
"Wow, itu pasti kode Delphi yang benar-benar mengerikan jika entah bagaimana berhasil melakukan 3-6x lebih lambat daripada implementasi Lisp!" Benar, saya akan menghitungnya sebagai kegagalan saya karena tidak menjelaskannya dengan lebih baik. Implementasi Lisp mampu mengubah ekspresi pengguna menjadi ekspresi Lisp - proses yang sangat mudah - dan kemudian mengkompilasi ekspresi Lisp ke kode asli (dengan optimisasi penuh). Itulah arti dari Aturan Kesepuluh Greenspun.
Michael Lenaghan
1
Jawaban yang fantastis! Saya akan memilihnya, setidaknya sampai yang lebih baik muncul :) Satu pertanyaan: Anda mengatakan Anda membuat keputusan untuk pergi dengan Chez Scheme berdasarkan keadaan lapangan "dulu sekali". Bisakah Anda menentukan satu tahun?
SuperElectric
11
Poin itu, bahwa implementasi LISP bebas untuk mengkompilasi sesuatu ke kode mesin, daripada mengandalkan juru bahasa, lebih halus dan sangat berguna. Buku "Let Over Lambda" menunjukkan inilah tepatnya mengapa paket regexp Common LISP portabel, yang mengkloning sintaks PERL regexp, mengungguli PERL oleh faktor yang signifikan. PERL, di sisi bawah, memiliki juru bahasa regexp. Paket Common LISP mengkompilasi regexps ke kode.
John R. Strohm
37

Saya biasanya tidak suka menempelkan tautan sebagai jawaban, tetapi saya menulis artikel blog tentang hal ini. Ini tidak lengkap, tetapi mendapat beberapa poin utama.

http://symbo1ics.com/blog/?p=729

Sunting : Berikut adalah poin-poin prinsipnya:

  1. KEBERADAAN : Kedua lisps muncul setelah sekelompok lisps lainnya. Skema mengambil rute minimal, aksiomatik. CL mengambil rute barok.
  2. KASUS : Biasanya Skema sensitif terhadap huruf besar-kecil. CL tidak (meskipun bisa jadi). Ini terkadang terlewatkan, tetapi kepraktisannya diperdebatkan (oleh saya).
  3. NAMA : Nama-nama simbol dalam CL sering kali aneh dan membingungkan. TERPRI,, PROGNdll. Skema biasanya memiliki nama yang sangat masuk akal. Ini adalah sesuatu yang terlewatkan dalam CL.
  4. FUNGSI : CL memiliki fungsi namespace yang terpisah. Ini tidak ketinggalan dalam Skema. Memiliki satu namespace biasanya memungkinkan untuk pemrograman fungsional yang sangat bersih, yang seringkali sulit atau canggung di CL. Tapi itu harus dibayar --- Anda kadang-kadang harus mengaburkan nama seperti " list" menjadi " lst" dalam Skema.
  5. MACROS : Saya kehilangan makro kotor level rendah paling banyak di Skema. Ya, syntax-rulessemuanya baik-baik saja dan keren sampai Anda ingin benar-benar meretas beberapa hal. Di sisi lain, makro higienis kadang-kadang terlewatkan dalam CL. Tidak memiliki cara standar untuk melakukannya berarti menciptakan kembali roda.
  6. PORTABILITAS : Seringkali CL lebih portabel, meskipun kedua bahasa tersebut distandarisasi. CL lebih besar, dan karena itu ada lebih banyak fitur standar untuk digunakan tanpa perpustakaan eksternal. Ini juga berarti lebih banyak hal tergantung pada implementasi yang dapat dilakukan dengan mudah. Juga, Skema menderita memiliki satu triliun implementasi, yang sebagian besar agak tidak kompatibel. Ini membuat CL sangat diinginkan.
  7. PERPUSTAKAAN : Sangat terkait dengan poin terakhir saya. Skema memiliki SRFI tetapi tidak diakui secara universal. Tidak ada cara portabel untuk bekerja dengan perpustakaan. CL di sisi lain memang punya cara. Dan Quicklisp adalah hadiah dari dewa (Xach) --- semacam gudang perpustakaan untuk digunakan.
  8. IMPLEMENTASI : Skema menderita begitu banyak implementasi. Tidak ada implementasi kanonik yang nyata. CL di sisi lain memiliki beberapa kinerja tinggi yang sangat bagus atau implementasi penggunaan khusus (kinerja tinggi: SBCL, komersial: Allegro, tertanam: ECL, portable: CLISP, Java: ABCL, ...).

Walaupun saya hanya berbicara sebagai orang pertama sedikit di atas, harus jelas apa yang saya lewatkan dan apa yang tidak saya lakukan.

[Saya minta maaf jika ini terlalu umum. Sepertinya Anda mungkin menginginkan detail yang lebih spesifik. Ada beberapa spesifik di pos.]

Quadrescence
sumber
bagaimana dengan ringkasan teaser pendek (benar-benar)? ^^
Dave O.
2
Harap sebaris highlight. Jawaban harus berdiri sendiri.
1
@Dave O. dan @ Thorbjørn Ravn Andersen: Menambahkan ringkasan seperti yang diminta. Terima kasih.
Quadrescence
2
"Rute barok"! Benar-benar cara yang bagus untuk menggambarkannya.
Mark C
Lisp umum adalah case-sensitive, tetapi mengonversi inputnya menjadi huruf besar sebelum mengevaluasinya. Anda bisa mendapatkan huruf kecil dalam simbol dengan mengutipnya. Masalah nama adalah karena Skema menyingkirkan nama-nama lama yang buruk dan CL tidak.
David Thornley
25

Saya baru-baru ini memulai proyek rumah menggunakan perpustakaan yang memiliki versi C dan versi Java. Saya ingin menggunakan Lisp untuk proyek tersebut, dan saya menghabiskan sekitar satu bulan bimbang antara menggunakan Common Lisp, Skema atau Clojure. Saya memiliki beberapa pengalaman dengan ketiganya, tetapi hanya proyek mainan. Saya akan menceritakan sedikit tentang pengalaman saya dengan masing-masing dari mereka sebelum memberi tahu Anda mana yang akhirnya saya pilih.

PLT Racket memiliki IDE yang bagus yang tidak hanya memungkinkan Anda mengevaluasi ekspresi dari editor, tetapi juga memungkinkan Anda mengetikkan tanda kurung alih-alih parens, mengubahnya kembali ke parens yang sesuai. Racket juga memiliki satu set perpustakaan besar dengan instalasi dan bahkan lebih banyak tersedia untuk diunduh. Visual debugger juga bermanfaat.

Implementasi Common Lisp (SBCL) saya tidak memiliki IDE, tetapi biasanya dengan implementasi CL open-source untuk menggunakan Emacs dan SLIME. Kombinasi ini bisa sangat efisien. Seiring dengan kemampuan untuk mengevaluasi ekspresi saat Anda mengetikkannya ke file sumber, ada juga REPL yang memiliki semua perintah pengeditan emacs, sehingga penyalinan kode dapat berjalan dengan efisien dua arah. Bahkan objek yang ditampilkan dalam buffer REPL dapat disalin dan ditempelkan. Alt+(dan Alt+)efisien untuk berurusan dengan tanda kurung dan indentasi yang cocok.

Semua fitur Emacs di atas juga tersedia untuk Clojure. Pengalaman mengedit saya dengan Clojure mirip dengan Lisp. Java interop bekerja dengan baik, dan saya ingin melakukan proyek Clojure begitu matang.

Saya dapat mengakses perpustakaan menggunakan ketiganya (Common Lisp, Racket, dan Clojure), tetapi saya akhirnya memilih Common Lisp untuk proyek tersebut. Faktor penentu adalah bahwa FFI lebih mudah digunakan di Common Lisp. CFFI memiliki manual yang sangat baik dengan kode contoh dan penjelasan terperinci dari setiap metode. Saya bisa membungkus 20 fungsi C dalam satu sore dan tidak harus menyentuh kode sejak itu.

Faktor lainnya adalah bahwa saya lebih akrab dengan Common Lisp daripada dengan Clojure atau Skema R6RS. Saya telah membaca sebagian besar buku-buku Praktis Common Lisp dan Graham, dan saya merasa nyaman dengan Hyperspec. Ini bukan kode "lispy", tapi saya yakin itu akan berubah saat saya mendapatkan lebih banyak pengalaman.

Larry Coleman
sumber
Terima kasih untuk detailnya! Apakah saya mengerti Anda dengan benar bahwa Anda pikir FFI SBCL lebih mudah digunakan daripada Clojure? Jika demikian, saya akan cukup terkejut dengan itu, mengingat bahwa Anda bisa memanggil metode Java langsung dari Clojure tanpa harus membungkusnya. (Atau apakah Anda juga perlu memanggil kode asli?)
SuperElectric
6
@SuperElectric: Memanggil metode Java "bawaan" dari Clojure adalah sepele; memanggil metode Java yang ada di pustaka yang diunduh: tidak begitu banyak. Saya benar-benar menghabiskan lebih banyak waktu untuk mendapatkan jalur classpath dan impor yang benar daripada yang saya butuhkan untuk mendapatkan metode C pertama saya bekerja dari SBCL dengan CFFI. Tapi saya bukan ahli Java, jadi Mileage Anda Mungkin Bervariasi.
Larry Coleman
21

Saya memprogram CL dan Racket.

Saya sedang mengembangkan situs Web sekarang di Common Lisp, dan saya menulis serangkaian program in-house untuk majikan saya sebelumnya di Racket.

Untuk kode in-house, saya memilih Racket (kemudian dikenal sebagai Skema PLT) karena majikannya adalah toko Windows, dan saya tidak bisa membuat mereka membayar LispWorks. Satu-satunya yang baik open source implementasi CL untuk Windows adalah (dan masih) CCL, yang membutuhkan dukungan SSE dalam prosesor. Majikannya, karena murah, menggunakan perangkat keras Zaman Batu. Bahkan jika majikan memiliki perangkat keras yang layak, satu-satunya pustaka GUI yang berakibat pada Common Lisp adalah McCLIM, yang hanya berfungsi pada Unix. Racket memiliki pustaka GUI yang bagus yang berfungsi pada Unix dan Windows, yang sangat penting untuk kesuksesan proyek saya.

Saya menghabiskan lebih dari setahun memasang dengan editor DrRacket primitif. EMACS tidak bisa mengubah versi GUI dari Racket, yang kemudian dikenal sebagai MrEd, menjadi inferior-lisp di Windows. Saya harus melakukannya tanpa dapat mengevaluasi ekspresi pada kursor dengan satu penekanan tombol. Sebagai gantinya, saya harus secara manual memilih ekspresi S, menyalinnya, klik pada jendela REPL (karena tidak ada penekanan tombol untuk beralih ke itu), lalu tempelkan ekspresi S. Saya juga harus melakukannya tanpa editor yang bisa menunjukkan kepada saya argumen yang diharapkan dari fungsi atau makro yang saya gunakan. DrRacket bukan pengganti SLIME.

Majikan menggunakan database berpemilik dengan XML API yang rumit yang membutuhkan banyak informasi yang tampaknya tidak perlu untuk dapat menanggapi versi kueri SELECT versi. Saya memutuskan untuk menggunakan HTMLPrag baik untuk memancarkan XML ke API ini, dan untuk mem-parsing tanggapan. Itu bekerja dengan baik.

Saya harus mempelajari sistem makro "sintaks kasus" Racket yang terlalu rumit untuk menulis makro yang memungkinkan saya berinteraksi dengan XML API yang terlalu rumit dengan mengetikkan formulir yang tampak seperti SQL. Bagian ini akan jauh lebih mudah jika saya memiliki DEFMACRO yang saya miliki. Namun, hasil akhirnya masih mulus meskipun butuh upaya lebih untuk mencapainya.

Selain itu, saya harus melakukannya tanpa makro Common Lisp LOOP. Racket mulai memberikan alternatif hanya setelah saya menulis sebagian besar kode, dan alternatif itu masih menyebalkan dibandingkan dengan LOOP (meskipun tim pengembangan Racket bersikeras itu lebih baik - mereka salah). Saya akhirnya menulis banyak nama LET form yang menggunakan "mobil" dan "cdr" untuk beralih pada daftar.

Berbicara tentang mobil dan cdr, tidak ada yang lebih membuat frustrasi daripada interpretasi Skema tentang (mobil '()) sebagai kesalahan. Saya mengambil keuntungan dari sensitivitas case Racket dan mengimplementasikan CAR dan CDR, yang memiliki semantik Common Lisp. Namun, pemisahan '() dan #f membuatnya jauh lebih tidak berguna untuk mengembalikan' () sebagai nilai default.

Saya juga akhirnya menerapkan kembali UNWIND-PROTECT, dan menemukan sistem restart saya sendiri untuk mengisi celah yang ditinggalkan oleh Racket. Komunitas Racket perlu belajar bahwa memulai ulang sangat berguna, dan mudah diterapkan.

Formulir nilai-nilai Racket terlalu bertele-tele, jadi saya menerapkan MULTIPLE-VALUE-BIND. Ini benar-benar diperlukan, karena Racket mengharuskan Anda untuk menerima semua nilai yang dihasilkan, apakah Anda menggunakannya atau tidak.

Kemudian, saya mencoba untuk menulis klien eBay XML API di Common Lisp, hanya untuk menemukan bahwa ia tidak memiliki apa pun seperti HTMLPrag. HTMLPrag berguna. Saya akhirnya melakukan proyek itu di Racket. Saya bereksperimen dengan fasilitas Programing Literate Racket, hanya untuk menemukan bahwa saya satu-satunya programmer di Bumi yang menemukan kode literasi yang ditulis dengan benar lebih sulit untuk diedit daripada kode biasa, atau kode literat "komentar berlebihan" yang ditulis dengan tidak tepat.

Proyek baru saya sedang dilakukan di Common Lisp, yang merupakan pilihan yang tepat karena komunitas Racket tidak percaya pada paralelisme, yang sangat penting untuk proyek ini. Satu-satunya hal yang saya pikir telah saya lewatkan dari Racket adalah kelanjutan. Namun, saya dapat melakukan apa yang saya butuhkan dengan menggunakan restart, dan, kalau dipikir-pikir, mungkin bisa melakukannya dengan penutupan sederhana.

Pemeras
sumber
2
Saya belum mencobanya sendiri, tetapi saya telah melihat posting blog dari orang-orang yang menggunakan program raket baris perintah dengan Emacs. Misalnya: bc.tech.coop/scheme/scheme-emacs.htm
Larry Coleman
5
Dalam semua keadilan sepertinya Anda datang ke Skema ingin menulis CL daripada mencoba mendekati hal-hal dari Skema POV idiomatik. Misalnya, tidakkah skema mendorong rekurisi daripada menggunakan loop?
Kereta luncur
Skema @ArtB tidak hanya mendorong rekursi, itu membutuhkannya , jadi tentu saja proyek yang disebutkan di atas menggunakan banyak rekursi. Dan itu hanya berfungsi untuk menambah pengulangan (Anda harus menyertakan salinan panggilan rekursif di setiap cabang condformulir, misalnya) dan bug (apakah saya menulis tes terminasi loop dengan benar saat itu?) Bahkan hari ini, saya mendapatkan kesan bahwa Racket terutama ditujukan untuk siswa dan bukan programmer profesional. Setiap kali saya mendengar seseorang selain saya menggunakannya, mereka menggunakan subbahasa "Siswa Awal" dan itu untuk kelas.
Membuang Akun
Jika Anda mengulang kode di COND apakah Anda mengatakan Anda hanya perlu fungsi lain?
Kereta luncur
@ArtB Suatu fungsi untuk memanggil fungsi loop dengan argumen yang berbeda? Itu tidak ada gunanya. Anda melihat pengulangan semacam itu di hampir semua kode Skema siapa pun. Bahkan ada contoh dalam kode sumber Racket sendiri.
Membuang Akun
5

Skema dirancang dengan kompilasi terpisah dalam pikiran. Sebagai akibatnya, kekuatan makro-makronya seringkali sangat terbatas, bahkan dengan ekstensi yang memungkinkan defmacro gaya Lisp Umum alih-alih miskin, membatasi sistem makro higienis. Tidak selalu mungkin untuk mendefinisikan makro yang mendefinisikan makro lain, yang dimaksudkan untuk segera digunakan dalam baris kode berikutnya. Dan kemungkinan seperti itu sangat penting untuk mengimplementasikan penyusun eDSL yang efisien.

Tidak perlu disebutkan bahwa implementasi Skema dengan hanya makro higienis R5RS hampir tidak berguna bagi saya, karena gaya pemrograman saya tidak dapat diterjemahkan secara memadai ke dalam kebersihan.

Untungnya, ada implementasi Skema (mis., Racket) yang tidak memiliki batasan itu.

Logika SK
sumber
1
Hai, saya baru saja mulai membasahi kaki saya dengan Skema belakangan ini menggunakan Racket. Maukah Anda memberikan contoh cepat menggunakan makro tidak higienis di Racket? Jenis makro yang tersedia sepertinya adalah salah satu poin yang paling diperdebatkan antara CL dan Skema.
orange80
@ orange80, satu-satunya pendekatan adalah menggunakan docs.racket-lang.org/mzlib/mzlib_defmacro.html Dan, tentu saja, dalam mode R6RS ada cara yang kurang ketat.
SK-logic
@ SK-logika apa yang Anda lakukan dengan makro yang sangat tidak berperasaan?
Kereta luncur
1
@ ArtB, saya menerapkan eDSL sebagai fungsi kompiler yang mungkin cukup banyak dengan AST sumbernya. Kebersihan adalah gangguan total dalam pendekatan semacam itu. Anda dapat melihat cara kerjanya: github.com/combinatorylogic/mbase
SK-logic