Menggunakan generator dan lambda, kita bisa melakukan pemrograman fungsional dengan Python. Anda juga dapat mencapai hal yang sama dengan Ruby.
Jadi pertanyaannya adalah: mengapa kita perlu bahasa pemrograman fungsional spesifik seperti Erlang, Haskell, dan Skema? Adakah yang berbeda dari bahasa pemrograman fungsional spesifik ini? Mengapa kita tidak bisa menggunakan Python saja untuk pemrograman fungsional?
programming-languages
python
functional-programming
Joshua Partogi
sumber
sumber
Jawaban:
Saya menghargai pertanyaan itu, karena saya pribadi penggemar berat Python dan gaya pemrograman fungsional. Saya memiliki latar belakang yang panjang dalam Python dan saya mulai mempelajari Haskell baru-baru ini, jadi inilah beberapa poin berdasarkan pengalaman pribadi saya tentang perbedaan antara bahasa-bahasa ini juga, dari perspektif fungsional.
Kemurnian
Bahkan jika Anda tidak peduli tentang kemurnian fungsi (yaitu tidak memiliki efek samping) sebagai prinsip, itu memang memiliki efek praktis pada betapa mudahnya membaca kode dan alasan tentang hal itu. Bahkan jika Anda mempertahankan kemurnian dalam fungsi Python Anda sendiri, ada perbedaan besar dalam membuat kompiler menegakkan kemurnian dan, yang paling penting, memiliki perpustakaan standar yang dibangun berdasarkan persyaratan kemurnian dan struktur data yang tidak dapat diubah.
Performa
Anda mungkin atau mungkin tidak peduli dengan kinerja tergantung pada apa domain aplikasi Anda, tetapi pengetikan statis dan kemurnian yang dijamin memberikan kompiler lebih banyak untuk dikerjakan, dibandingkan dengan Python dan bahasa dinamis lainnya (walaupun saya harus mengakui bahwa PyPy menjadi hebat terobosan, dan misalnya LuaJIT berbatasan dengan ajaib).
Optimasi Tail-call
Terkait dengan kinerja, tetapi sedikit berbeda. Bahkan jika Anda tidak terlalu peduli dengan kinerja runtime, tidak memiliki optimasi panggilan ekor (terutama untuk rekursi ekor) membatasi cara-cara Anda dapat mengimplementasikan algoritma dengan Python tanpa mencapai batas tumpukan.
Sintaksis
Ini adalah alasan terbesar mengapa saya mulai melihat bahasa fungsional "nyata" daripada hanya menggunakan Python dengan gaya fungsional. Walaupun saya berpikir bahwa Python memiliki sintaks yang sangat ekspresif secara umum, Python memiliki beberapa titik lemah khusus untuk pengkodean fungsional. Sebagai contoh:
f = g . h
vs.f = lambda *arg: g(h(*arg))
f = map g
vs.f = functools.partial(map, g)
sum = reduce (+) lst
vs.sum = reduce(operator.add, lst)
y = func1 $ func2 $ func3 x
lebih mudah dibaca daripaday = func1(func2(func3(x)))
, setelah Anda terbiasa dengan notasi itu.sumber
Inilah perbedaan terpenting:
Haskell
Haskell dan Erlang
Erlang
Skema
Semua bahasa
Juga, Anda harus melihat bahasa dari keluarga ML seperti SML, Ocaml dan F # dan Scala, yang menggabungkan OO dan pemrograman fungsional dengan cara baru. Semua bahasa ini memiliki fitur menarik yang unik.
sumber
Sulit untuk mendefinisikan dengan tepat apa itu "bahasa fungsional" - dari bahasa yang Anda cantumkan, hanya Haskell yang murni fungsional (semua yang lain mengadopsi semacam pendekatan hybrid). Ada fitur bahasa tertentu yang sangat membantu untuk pemrograman fungsional, dan Ruby dan Python tidak memiliki cukup dari mereka untuk menjadi lingkungan yang sangat baik untuk FP. Berikut adalah daftar periksa pribadi saya, sesuai urutan kepentingannya:
Kebutuhan untuk (1) harus jelas - fungsi tingkat tinggi sangat sulit tanpa fungsi kelas satu. Ketika orang berbicara tentang Ruby dan Python sebagai bahasa yang baik untuk FP, mereka biasanya membicarakan hal ini. Namun, fitur khusus ini diperlukan tetapi tidak cukup untuk membuat bahasa yang baik untuk FP.
(2) telah menjadi kebutuhan tradisional untuk KB sejak Skema ditemukan. Tanpa TCO, tidak mungkin untuk memprogram dengan rekursi yang dalam, yang merupakan salah satu pilar FP, karena Anda mendapatkan stack overflow. Satu-satunya bahasa "fungsional" (menurut definisi populer) yang tidak memiliki ini adalah Clojure (karena keterbatasan JVM), tetapi Clojure memiliki beragam peretasan untuk mensimulasikan TCO. (FYI, Ruby TCO adalah implementasi khusus , tetapi Python khusus tidak mendukungnya .) Alasan TCO harus dijamin adalah bahwa jika itu spesifik implementasi, fungsi rekursif yang dalam akan pecah dengan beberapa implementasi, sehingga Anda tidak bisa benar-benar gunakan semuanya.
(3) adalah hal besar lain yang dimiliki bahasa fungsional modern (terutama Haskell, Erlang, Clojure, dan Scala) yang tidak dimiliki oleh Ruby dan Python. Tanpa membahas terlalu banyak detail, immutability yang dijamin menghilangkan seluruh kelas bug, terutama dalam situasi bersamaan, dan memungkinkan hal-hal yang rapi seperti struktur data yang persisten . Sangat sulit untuk mengambil manfaat dari manfaat ini tanpa dukungan tingkat bahasa.
(4) bagi saya adalah hal yang paling menarik tentang bahasa murni fungsional (bukan bahasa hibrida). Pertimbangkan fungsi Ruby yang sangat sederhana berikut:
Ini terlihat seperti fungsi murni, tetapi karena operator kelebihan beban, ini dapat mengubah parameter atau menyebabkan efek samping seperti mencetak ke konsol. Tidak mungkin seseorang akan membebani
+
operator untuk memiliki efek samping, tetapi bahasa tidak memberikan jaminan. (Hal yang sama berlaku untuk Python, walaupun mungkin tidak dengan contoh khusus ini.)Di dalam bahasa yang murni fungsional, di sisi lain, ada jaminan tingkat bahasa yang fungsinya transparan secara referensial. Ini memiliki banyak keuntungan: fungsi murni dapat dengan mudah ditulis; mereka dapat dengan mudah diuji tanpa bergantung pada negara global apa pun; dan nilai-nilai dalam fungsi dapat dievaluasi dengan malas atau paralel tanpa khawatir tentang masalah konkurensi. Haskell mengambil keuntungan penuh dari ini, tetapi saya tidak cukup tahu tentang bahasa fungsional lain untuk mengetahui apakah mereka melakukannya.
Semua yang dikatakan, dimungkinkan untuk menggunakan teknik FP di hampir semua bahasa (bahkan Jawa). Misalnya, Google MapReduce terinspirasi oleh ide-ide fungsional, tetapi sejauh yang saya tahu mereka tidak menggunakan bahasa "fungsional" untuk proyek-proyek besar mereka (saya pikir mereka kebanyakan menggunakan C ++, Java, dan Python).
sumber
Bahasa yang Anda sebutkan sangat berbeda.
Sementara Python dan Ruby adalah bahasa yang diketik secara dinamis, Haskell diketik secara statis. Erlang adalah bahasa bersamaan dan menggunakan model Aktor dan sangat berbeda dari semua bahasa lain yang Anda sebutkan.
Python dan Ruby memiliki banyak konstruksi imperatif sementara dalam bahasa fungsional yang lebih murni seperti Haskell, semuanya mengembalikan sesuatu atau dengan kata lain semuanya adalah fungsi.
sumber
Terlambat ke pesta seperti biasa, tetapi akan mengatakan banyak hal.
Bahasa pemrograman fungsional bukan bahasa yang memungkinkan pemrograman fungsional. Jika kita menggunakan definisi itu, maka hampir semua bahasa di mana saja adalah bahasa pemrograman fungsional. (Hal yang sama berlaku untuk OOP, kebetulan. Anda dapat menulis dalam gaya OOP dalam C jika Anda suka. Jadi, menurut logika Anda, C adalah bahasa OOP.)
Apa yang membuat bahasa pemrograman fungsional bukanlah seperti yang Anda izinkan untuk diprogram, melainkan apa yang memungkinkan Anda memprogram dengan mudah . Itulah kuncinya.
Jadi, Python memiliki lambdas (yang sangat mirip dengan masalah penutupan mirip anemia) dan memberi Anda beberapa fungsi perpustakaan yang akan Anda lihat di perpustakaan fungsional juga seperti "map" dan "fold". Ini tidak cukup untuk membuatnya menjadi bahasa pemrograman fungsional, karena sulit untuk mustahil untuk secara konsisten memprogram dalam gaya fungsional yang tepat di dalamnya (dan bahasa jelas tidak memaksakan gaya ini!). Pada intinya Python adalah bahasa imperatif yang berkaitan dengan operasi manipulasi negara dan negara dan ini hanya bertentangan dengan ekspresi dan ekspresi semantik evaluasi bahasa fungsional.
Jadi mengapa kita memiliki bahasa pemrograman fungsional ketika Python (atau Ruby (atau memasukkan bahasa pilihan Anda)) dapat "melakukan pemrograman fungsional"? Karena Python, dkk tidak dapat melakukan pemrograman fungsional yang tepat. Itu sebabnya.
sumber
Anda dapat melakukan pemrograman fungsional di Jawa (lihat misalnya http://functionaljava.org/ ). Anda juga dapat melakukan pemrograman berorientasi objek di C . Hanya saja tidak sebodoh itu.
Jadi memang kita tidak benar - benar membutuhkan Erlang, Haskell, Skema, atau bahasa pemrograman spesifik apa pun, tetapi semuanya mewakili pendekatan dan pertukaran yang berbeda, membuat beberapa tugas lebih mudah dan beberapa lebih sulit. Apa yang harus Anda gunakan tergantung pada apa yang ingin Anda capai.
sumber
Pertanyaan ini dapat diterapkan pada jumlah bahasa dan paradigma yang tak terbatas.
Sebagian besar, jika tidak semua bahasa ada karena alasan tertentu. Mereka ada karena seseorang memiliki kebutuhan yang tidak ada bahasa saat ini diisi, atau diisi dengan buruk. (Ini tentu saja tidak berlaku untuk setiap bahasa, tapi saya rasa itu berlaku untuk sebagian besar bahasa yang terkenal.) Misalnya, python awalnya dikembangkan untuk berinteraksi dengan OS Amoeba [ 1 , 2 ] dan Erlang diciptakan untuk membantu dalam pengembangan aplikasi teleponi [ 3 ]. Jadi satu jawaban untuk pertanyaan "Mengapa kita membutuhkan bahasa fungsional lain?" bisa saja, karena [masukkan-nama-dari-seseorang-yang-tahu-bagaimana-desain-bahasa] tidak suka cara python melakukannya.
Itu cukup menyimpulkan apa yang saya pikir jawabannya. Meskipun Anda dapat melakukan apa saja dengan python yang dapat Anda lakukan dengan bahasa fungsional, apakah Anda benar-benar ingin melakukannya? Segala sesuatu yang dapat Anda lakukan di C, Anda bisa lakukan dalam perakitan, tetapi apakah Anda ingin? Bahasa yang berbeda akan selalu menjadi yang terbaik dalam melakukan hal yang berbeda, dan begitulah seharusnya.
sumber
Pemrograman fungsional adalah tentang paradigma desain seperti halnya tentang fitur bahasa tertentu. Atau, dengan kata lain, lambdas dan fungsi peta tidak membuat bahasa pemrograman fungsional. Python dan Ruby memiliki beberapa fitur yang terinspirasi oleh bahasa pemrograman fungsional, tetapi Anda umumnya masih menulis kode dengan cara yang sangat penting. (Ini seperti C: Anda dapat menulis kode seperti OO dalam C, tetapi tidak ada yang menganggap serius C sebagai bahasa OO.)
Lihat: pemrograman fungsional bukan hanya tentang lambdas, atau
map
, atau fungsi tingkat tinggi. Ini tentang desain . Suatu program yang ditulis dalam bahasa pemrograman fungsional "benar" memecahkan masalah melalui komposisi fungsi. Sementara program yang ditulis dalam Ruby atau Python dapat menggunakan fitur seperti FP, mereka umumnya tidak membaca seperti sekumpulan fungsi yang dikomposisikan.sumber
Setiap bahasa fungsional yang Anda sebutkan cocok dengan niche tertentu dengan cukup baik dan pola-pola idiomatik yang mendorong masing-masing membuatnya sangat cocok untuk tugas-tugas tertentu yang tidak mungkin untuk dicapai dengan Python kecuali Anda membangun perpustakaan besar modul pembantu. Salah satu keunggulan niche yang paling jelas adalah model konkurensi Erlang. Yang lain juga memiliki kekuatan yang sama.
sumber
Setiap konsep yang tersedia dalam lambda-calculus, LISP, dan Scheme tersedia dalam Python, jadi, ya, Anda dapat melakukan pemrograman fungsional di dalamnya. Apakah nyaman atau tidak adalah masalah konteks dan selera.
Anda dapat dengan mudah menulis penerjemah LISP (atau bahasa fungsional lainnya) dengan Python (Ruby, Scala) (apa artinya itu?). Anda dapat menulis penerjemah untuk Python menggunakan fungsional murni, tetapi itu akan membutuhkan banyak pekerjaan. Bahkan bahasa "fungsional" adalah multi-paradigma saat ini.
Buku tua dan indah ini memiliki sebagian besar (walaupun tidak semua) jawaban tentang apa esensi pemrograman fungsional.
sumber
eval()
fungsi, yang diperlukan untuk kode adalah data , tetapi ia melangkah lebih jauh: ia memungkinkan Anda memodifikasi sebagian besar lingkungan runtime, seperti di LISP.eval()
adalah metaprogramming runtime. Terkadang bermanfaat, tetapi sangat mahal. Lisp macro berbeda, ini adalah waktu penyusunan metaprogramming. Ini tidak tersedia dalam Python dalam bentuk apa pun yang dapat digunakan.Karena Python juga dapat memprogram dalam gaya non-fungsional, dan itu tidak cukup baik untuk purist FP. Namun, lebih banyak pembuat kode pragmatis dapat menikmati manfaat gaya fungsional tanpa menjadi dogmatis tentang hal itu:
- John Hughes, Mengapa pemrograman fungsional penting
sumber
goto
ada di luar itu mengerikan.call-with-current-continuation
,.