Bisakah Lisp dengan mudah digunakan dengan cara yang fungsional dan tidak dapat diubah?

Saya berasal dari latar belakang Haskell, dan saya ingin belajar Common Lisp.

Sudah dibahas dengan baik bahwa CL adalah "bukan bahasa fungsional", tapi saya ingin tahu apakah CL dapat digunakan sebagai bahasa fungsional.

Misalnya, apakah mungkin untuk menggunakan semua tipe data dengan cara yang tidak dapat diubah? Tabel hash Lisp yang umum tampaknya disetel menggunakan setf, yang jelas-jelas memiliki orientasi yang bisa berubah. Apakah ada cara untuk menggunakannya dengan cara yang tidak dapat diubah?

Selain aspek "IO" dari Common Lisp (aspek "murni" dari Haskell) tempat saya berinteraksi dengan file, jaringan, dll., dapatkah saya menulis kode dengan nyaman di Lisp dan yakin bahwa kode tersebut akan memiliki transparansi referensial?

Bisakah saya mengharapkan properti semacam ini dari perpustakaan populer yang tersedia di Common Lisp?

Apakah ada idiom atau aspek umum bahasa yang membuat hal ini menjadi sulit?


person Community    schedule 26.01.2019    source sumber
comment
Common Lisp sengaja dirancang untuk mengakomodasi setidaknya pemrograman imperatif, pemrograman fungsional, pemrograman berorientasi objek. Cara Anda menggunakannya tentu saja tergantung pada Anda. Jika Anda menulis program tanpa efek samping apa pun, Anda akan menghasilkan program dengan transparansi referensial (dengan kata lain, dalam bahasa spesifikasi kemungkinan efek samping dari operator didokumentasikan dengan baik).   -  person Renzo    schedule 26.01.2019
comment
Mempelajari Common Lisp seperti Haskell dengan tanda kurung tidak terlalu berguna, karena Common Lisp adalah bahasa dan ekosistem yang sangat berbeda. 'ketika di Roma, lakukan seperti yang dilakukan orang Romawi'.   -  person Rainer Joswig    schedule 26.01.2019
comment
Anda mengatakan Sudah dibahas dengan baik bahwa CL bukanlah bahasa fungsional, tetapi interpretasi saya adalah bahwa CL bukan hanya bahasa fungsional. Jika Lisp bukan bahasa fungsional, lalu apa?   -  person coredump    schedule 26.01.2019
comment
Lihat mis. github.com/danlentz/cl-ctrie   -  person coredump    schedule 26.01.2019
comment
@RainerJoswig bukankah itu bagian dari filosofi Lisp bahwa bahasa harus beradaptasi dengan kasus penggunaan, daripada memaksa semua orang untuk menggunakannya dengan cara yang sama?   -  person leftaroundabout    schedule 26.01.2019
comment
@leftaroundabout: mengapa mengabaikan bahasa Common Lisp yang ada dengan 1000+ operator, tipe data, struktur kontrol, variabel, ... mungkin lebih baik daripada kecewa karena CL bukan Haskell dan hanya pengganti Haskell yang buruk. Perlu diingat juga bahwa membentuk bahasa untuk mendukung pemrograman bebas efek samping dengan cara yang efisien mungkin bukan tugas pemula tanpa pengetahuan bahasa yang lebih dalam...   -  person Rainer Joswig    schedule 26.01.2019
comment
cara untuk menggunakan [apa pun] dengan cara yang tidak dapat diubah adalah dengan selalu memutasi salinan, bukan yang asli. -- CL adalah bahasa imperatif, IMO. Bahasa imperatif apa pun dapat digunakan untuk membuat kode secara fungsional (misalnya C). Aturan evaluasi dan namespace fungsi yang terpisah akan membuatnya terasa sangat asing, menurut saya, dibandingkan dengan Haskell. Tapi segalanya mungkin terjadi di CL.   -  person Will Ness    schedule 26.01.2019
comment
Menurut saya, kekuatan CL adalah multiparadigma. Tentu, Anda dapat membentuk bahasanya sesuai keinginan dan keinginan Anda. Tetapi juga bagian dari filosofi CL adalah menggunakan paradigma yang berbeda (FP, OOP, imperatif, pemrograman logis, ...) untuk bagian program yang tepat. Dan dalam hal kinerja, akan sangat efisien jika menggunakan mutasi - tetapi dengan cara yang terbatas.   -  person Gwang-Jin Kim    schedule 28.01.2019


Jawaban (1)


Ya, tentu saja, tetapi bergantung pada seberapa besar Anda ingin pembatasan diterapkan, jarak tempuh Anda mungkin berbeda.

Hanya saja, jangan bermutasi

Anda cukup menghindari setf dan semua tempat mesin. Jika Anda harus menggunakan tabel hash atau vektor, Anda akan banyak menyalin, namun untuk banyak aplikasi, overhead pengumpulan sampah masih dapat dikelola. Di banyak tempat, Anda dapat menggunakan alists atau plists, yang dapat ditangani hampir seperti struktur data fungsional. Beberapa utilitas berguna ada di alexandria, e. G. copy-hash-table, yang memiliki argumen key untuk benar-benar melakukan sesuatu seperti map-hash-table hipotetis. Semua kebaikan fungsional lainnya, seperti fungsi tingkat tinggi, map, reduce, remove dll. tersedia dalam banyak rasa. Selain itu, kasus penggunaan tertentu dapat diselesaikan secara deklaratif di loop.

Ada juga perpustakaan yang membuat gaya ini lebih mudah secara eksplisit, misalnya. G. modf.

Ini bisa membawa Anda cukup jauh. Saya menganggapnya mudah untuk melihat di mana Anda melanggar transparansi referensial dan menghindarinya.

Gunakan struktur data fungsional

Ada FSet, yang memberi Anda banyak struktur data fungsional, dan ada sycamore, yang memberikan lebih banyak lagi.

Gunakan transduser

SERIES muncul di CLtL2 pada tahun 1990 dan hampir menjadi standar pada tahun 1994. Ada juga taps, yang menambahkan beberapa fungsi berguna.

Merenungkan

Secara pribadi, saya tidak terlalu keras lagi mengejar kemurnian. Terkadang, memutasi suatu tempat dalam satu lingkaran lebih mudah dipahami daripada melakukan beberapa pengikatan dalam luasan yang berbeda. Saya hanya membatasi mutasi; ini mirip dengan konsep kepemilikan data. Namun, saya ingin memiliki kemurnian dalam skala yang lebih besar, baik di memori maupun di disk, misalnya. G. log tambahan saja, database (bknr.datastore).

person Svante    schedule 26.01.2019