Saya tertarik belajar pemrograman fungsional dengan lebih baik. Untuk melakukannya, tampak jelas bahwa saya harus memaksakan diri untuk menggunakan bahasa pemrograman fungsional semurni mungkin. Oleh karena itu, saya di sini meminta, kurang lebih, untuk pemesanan bahasa pemrograman fungsional sesuai dengan kemurniannya.
Sepertinya bagi saya bahwa akan lebih praktis untuk mempelajari Lisp atau Clojure (atau Skema, atau Scala, dll.), Tetapi untuk apa yang saya dengar baru-baru ini, Haskell akan sangat sulit dikalahkan dalam mengajarkan prinsip-prinsip pemrograman fungsional kepada seseorang. Saya belum yakin tentang ini, jadi saya bertanya kepada Anda: yang merupakan bahasa pemrograman fungsional paling murni? Suatu pemesanan akan bagus jika beberapa bersaing untuk mendapatkan gelar yang luar biasa dari bahasa pemrograman fungsional yang paling murni.
Jawaban:
Tidak ada skala untuk menilai tingkat kemurnian bahasa fungsional. Jika bahasa memungkinkan efek samping itu tidak murni, jika tidak murni. Dengan definisi ini, Haskell, Mercury, Clean dll adalah bahasa fungsional murni; sedangkan Scala, Clojure, F #, OCaml dll adalah yang tidak murni.
EDIT: Mungkin saya seharusnya mengatakan ini sebagai "jika bahasa tidak memungkinkan efek samping tanpa membiarkan tipe sistem tahu , itu murni. Kalau tidak, itu tidak murni.".
sumber
IO
monad). Hanya saja kode penyebab efek samping ditandai dengan jelas seperti itu. Saya tidak berpikir itu berguna untuk berbicara dari / tidak murni murni bahasa sama sekali (Haskell memungkinkan Anda program imperatif! Terkesiap!) Tetapi masih dapat berguna untuk berbicara dari potongan kode (fungsi, modul, program apa pun) sebagai murni /najis.IO
monad itu murni. Ini adalah pustaka runtime yang bukan, bukan kode Anda, karenamain
fungsi Anda pada dasarnya adalah transformator besar. (Sesuatu seperti dimain :: World -> World
belakang layar)program = "some C code"
, dan kemudian lingkungan runtime berhubungan dengan kode C. :-)Karena belajar adalah tujuan Anda, dan bukan menulis program sendiri, Anda tidak bisa mendapatkan yang lebih murni dari Kalkulus Lambda .
Kalkulus Lambda ada sebelum komputer ditemukan. Butuh beberapa ahli logika yang terampil untuk mengatasinya untuk mengetahui bagaimana melakukan pengurangan (untuk sementara waktu diteorikan bahwa hanya penambahan dan perkalian yang mungkin dilakukan).
Belajar bagaimana booleans dan angka dan
if
dapat ditemukan dari yang tampaknya tidak akan memasukkan lebih banyak gas ke tangki Anda, tetapi itu akan membuat tangki Anda jauh lebih besar.sumber
-1
.Pada dasarnya, bahasa yang tidak murni tidak benar-benar berbeda dari bahasa imperatif yang lebih akrab, terutama sekarang karena banyak trik fungsional telah disalin. Yang berbeda adalah gaya - bagaimana Anda memecahkan masalah.
Apakah Anda menganggap Haskell sebagai murni, atau menganggap monad IO sebagai ketidakmurnian, gaya Haskell adalah bentuk ekstrim dari gaya ini dan layak untuk dipelajari.
Haskell IO Monad berasal dari teori matematika (tentu saja) monad. Namun, untuk programer yang penting, saya pikir cara mundur untuk tiba di monad lebih masuk akal.
Fase satu - bahasa fungsional murni dapat dengan mudah mengembalikan nilai string besar sebagai hasilnya. String besar ini dapat menjadi kode sumber dari program imperatif, diturunkan dengan cara fungsional murni dari beberapa parameter yang menentukan persyaratan. Anda kemudian dapat membangun kompilator "tingkat lebih tinggi" yang menjalankan pembuat kode Anda, lalu secara otomatis memasukkan kode yang dihasilkan ke kompiler bahasa imperatif.
Fase dua - daripada menghasilkan kode sumber tekstual, Anda menghasilkan pohon sintaksis yang sangat diketik. Kompiler bahasa imperatif Anda diserap ke dalam kompiler "level lebih tinggi" Anda, dan menerima AST secara langsung sebagai kode sumber. Ini jauh lebih dekat dengan apa yang Haskell lakukan.
Ini masih canggung. Misalnya Anda memiliki dua jenis fungsi yang berbeda - yang dievaluasi selama fase pembuatan kode dan yang dijalankan ketika program yang dihasilkan dijalankan. Ini agak seperti perbedaan antara fungsi dan template di C ++.
Jadi, untuk fase 3, buat keduanya sama - fungsi yang sama dengan sintaksis yang sama dapat dievaluasi sebagian selama "pembuatan kode", atau dievaluasi sepenuhnya, atau tidak dievaluasi sama sekali. Lebih lanjut, buang semua simpul AST looping yang mendukung rekursi. Bahkan, buang ide AST node sebagai jenis data khusus sama sekali - tidak memiliki AST "nilai literal", hanya punya nilai dll.
Inilah yang dilakukan oleh IO monad - operator pengikat adalah cara menyusun "tindakan" untuk membentuk program. Tidak ada yang istimewa - hanya fungsi. Banyak ekspresi dan fungsi dapat dievaluasi selama "pembuatan kode", tetapi yang bergantung pada efek samping I / O harus ditunda evaluasi sampai run-time - bukan oleh aturan khusus, tetapi sebagai konsekuensi alami dari ketergantungan data pada ekspresi.
Monads secara umum hanyalah generalisasi - mereka memiliki antarmuka yang sama, tetapi menerapkan operasi abstrak secara berbeda, jadi alih-alih mengevaluasi ke deskripsi kode imperatif mereka mengevaluasi ke sesuatu yang lain sebagai gantinya. Memiliki antarmuka yang sama berarti ada beberapa hal yang dapat Anda lakukan untuk monad tanpa peduli monad mana, yang ternyata bermanfaat.
Deskripsi ini tidak diragukan lagi akan membuat purists head meledak, tetapi bagi saya itu menjelaskan beberapa alasan sebenarnya mengapa Haskell menarik. Ini mengaburkan batas antara pemrograman dan metaprogramming, dan menggunakan alat pemrograman fungsional untuk menemukan kembali pemrograman imperatif tanpa memerlukan sintaksis khusus.
Kritik yang saya miliki tentang C ++ templates adalah bahwa mereka adalah semacam bahasa terjemahan fungsional yang rusak murni dalam bahasa imperatif - untuk mengevaluasi fungsi dasar yang sama pada waktu kompilasi daripada pada saat run-time Anda harus mengimplementasikannya kembali menggunakan gaya yang sama sekali berbeda pengkodean. Dalam Haskell, sementara kenajisan harus diberi label seperti itu dalam tipenya, fungsi yang sama persis dapat dievaluasi baik dalam arti meta-pemrograman dan dalam arti run-time non-meta-pemrograman dalam program yang sama - tidak ada garis keras antara pemrograman dan metaprogramming.
Yang mengatakan, ada beberapa hal metaprogramming yang Haskell standar tidak bisa lakukan, pada dasarnya karena tipe (dan mungkin beberapa hal lainnya) bukan nilai kelas Ada beberapa varian bahasa yang mencoba mengatasinya.
Banyak hal yang saya katakan tentang Haskell dapat diterapkan dalam bahasa fungsional yang tidak murni - dan kadang-kadang bahkan bahasa imperatif. Haskell berbeda karena Anda tidak punya pilihan selain mengambil pendekatan ini - pada dasarnya memaksa Anda untuk mempelajari gaya kerja ini. Anda dapat "menulis C dalam ML", tetapi Anda tidak dapat "menulis C di Haskell" - setidaknya tidak tanpa mengetahui apa yang terjadi di bawah tenda.
sumber
Saya secara pribadi mengelompokkan bahasa dalam tiga tingkatan kemurnian fungsional:
Bahasa fungsional murni - yaitu bahasa yang memperlakukan seluruh program Anda sebagai fungsi murni dan menangani kemampuan berubah-ubah semata-mata melalui interaksi dengan runtime - Haskell mungkin merupakan contoh kanonik
Bahasa fungsional yang tidak murni - yaitu bahasa yang menekankan gaya fungsional tetapi memungkinkan efek samping. Clojure jelas dalam kategori ini (memungkinkan mutasi secara terkontrol sebagai bagian dari kerangka kerja STM-nya), juga OCaml atau F #
Bahasa multi-paradigma - ini bukan bahasa fungsional pertama dan terutama tetapi dapat mendukung gaya fungsional dengan menggunakan fungsi kelas satu dll. Scala adalah contoh yang baik di sini, saya juga meletakkan Common Lisp dalam kategori ini dan Anda bahkan bisa memasukkan bahasa seperti JavaScript .
Dalam situasi Anda, saya sarankan belajar Haskell dulu, lalu Clojure. Inilah yang saya lakukan dan itu bekerja dengan sangat baik untuk saya! Haskell cantik dan mengajarkan Anda prinsip-prinsip fungsional yang paling murni, Clojure jauh lebih pragmatis dan membantu Anda menyelesaikan banyak hal sementara masih sangat fungsional di hati.
Saya tidak benar-benar menghitung kategori ketiga sebagai bahasa fungsional (walaupun setelah mempelajari Haskell dan Clojure saya sering mendapati diri saya mengambil keuntungan dari teknik fungsional saat menggunakannya!)
sumber
Jika bahasa fungsional murni seperti itu, yang hanya memiliki fungsi murni (rutin yang tidak memiliki efek samping), maka itu sedikit tidak ada gunanya, karena tidak dapat membaca input atau menulis output;)
Karena ini benar-benar untuk belajar, saya pikir isolasi belum tentu yang cara untuk pergi. Pemrograman fungsional adalah sebuah paradigma. Penting untuk memahami paradigma mana yang cocok untuk masalah mana dan yang lebih penting, bagaimana mereka dapat dikombinasikan.
Selain itu, jika Anda mencari "kemurnian", Anda mungkin ingin melihat Pure . Namun perlu dicatat, kemudahan memanggil rutinitas C membuatnya tidak jelas secara fungsional (tetapi juga sangat kuat).
sumber
Bukan jawaban yang sepenuhnya serius, tetapi Unlambda harus menjadi penantang. Anda tidak bisa mendapatkan "fungsional murni" lebih dari kombinator SKI.
sumber
Erlang, Haskell, Skema, Scala, Clojure, dan F #
Pertanyaan ini mungkin akan membantu Anda dalam pencarian Anda juga .
sumber
set!
(antara lain) ...