Saya telah membaca beberapa teks tentang pemrograman deklaratif / fungsional (bahasa), mencoba Haskell dan juga menulis sendiri. Dari apa yang saya lihat, pemrograman fungsional memiliki beberapa keunggulan dibandingkan gaya imperatif klasik:
- Program tanpa kewarganegaraan; Tidak ada efek samping
- Concurrency; Bermain sangat bagus dengan meningkatnya teknologi multi-core
- Program biasanya lebih pendek dan dalam beberapa kasus lebih mudah dibaca
Produktivitas meningkat (contoh: Erlang)
Pemrograman imperatif adalah paradigma yang sangat lama (sejauh yang saya tahu) dan mungkin tidak cocok untuk abad ke-21
Mengapa perusahaan menggunakan atau program yang ditulis dalam bahasa fungsional masih sangat "langka"?
Mengapa, ketika melihat kelebihan pemrograman fungsional, apakah kita masih menggunakan bahasa pemrograman imperatif?
Mungkin terlalu dini untuk itu pada tahun 1990, tetapi hari ini?
functional-programming
pankrax
sumber
sumber
Jawaban:
Karena semua kelebihan itu juga kerugian.
Program dunia nyata adalah semua tentang efek samping dan mutasi. Ketika pengguna menekan tombol itu karena mereka ingin sesuatu terjadi. Ketika mereka mengetik sesuatu, mereka ingin negara itu menggantikan keadaan apa pun yang dulu ada di sana. Ketika Jane Smith dalam bidang akuntansi menikah dan mengubah namanya menjadi Jane Jones, basis data yang mendukung proses bisnis yang mencetak paycheque-nya lebih baik tentang penanganan mutasi semacam itu. Ketika Anda menembakkan senapan mesin pada alien, kebanyakan orang tidak secara mental memodelkan itu sebagai konstruksi alien baru dengan lebih sedikit titik hit; mereka memodelkan itu sebagai mutasi dari properti alien yang ada.
Ketika konsep-konsep bahasa pemrograman secara fundamental bekerja melawan domain yang dimodelkan, sulit untuk membenarkan menggunakan bahasa itu.
Masalahnya hanya didorong. Dengan struktur data yang tidak dapat diubah, Anda memiliki keamanan utas yang murah dengan biaya kemungkinan bekerja dengan data basi. Dengan struktur data yang bisa berubah, Anda mendapatkan keuntungan dengan selalu mengerjakan data baru dengan biaya harus menulis logika yang rumit untuk menjaga data tetap konsisten. Ini tidak seperti yang jelas lebih baik dari yang lain.
Kecuali dalam kasus di mana mereka lebih panjang dan sulit dibaca. Mempelajari cara membaca program yang ditulis dengan gaya fungsional adalah keterampilan yang sulit; orang tampaknya jauh lebih baik dalam memahami program sebagai serangkaian langkah yang harus diikuti, seperti resep, daripada sebagai serangkaian perhitungan yang harus dilakukan.
Produktivitas harus naik banyak untuk membenarkan biaya besar mempekerjakan programmer yang tahu cara memprogram dalam gaya fungsional.
Dan ingat, Anda tidak ingin membuang sistem kerja; sebagian besar programmer tidak membangun sistem baru dari awal, melainkan mempertahankan sistem yang ada, yang sebagian besar dibangun dalam bahasa non-fungsional. Bayangkan mencoba membenarkan hal itu kepada pemegang saham. Mengapa Anda membatalkan sistem penggajian kerja yang ada untuk membangun yang baru dengan biaya jutaan dolar? "Karena pemrograman fungsional itu mengagumkan" tidak mungkin menyenangkan para pemegang saham.
Pemrograman fungsional juga sangat tua. Saya tidak melihat bagaimana usia konsep itu relevan.
Jangan salah sangka. Saya suka pemrograman fungsional, saya bergabung dengan tim ini karena saya ingin membantu membawa konsep dari pemrograman fungsional ke dalam C #, dan saya pikir pemrograman dalam gaya yang tidak dapat diubah adalah cara masa depan. Tetapi ada biaya yang sangat besar untuk pemrograman dengan gaya fungsional yang tidak bisa begitu saja dihilangkan. Pergeseran menuju gaya yang lebih fungsional akan terjadi secara perlahan dan bertahap selama beberapa dekade. Dan itulah yang akan terjadi: perubahan menuju gaya yang lebih fungsional, bukan merangkul kemurnian dan keindahan Haskell dan meninggalkan C ++.
Saya membangun kompiler untuk mencari nafkah dan kami jelas merangkul gaya fungsional untuk generasi alat kompiler berikutnya. Itu karena pemrograman fungsional pada dasarnya cocok untuk jenis masalah yang kita hadapi. Masalah kita adalah semua tentang mengambil informasi mentah - string dan metadata - dan mengubahnya menjadi string dan metadata yang berbeda. Dalam situasi di mana mutasi terjadi, seperti seseorang mengetik di IDE, ruang masalah secara inheren cocok untuk teknik fungsional seperti secara bertahap membangun kembali hanya bagian-bagian pohon yang berubah. Banyak domain tidak memiliki properti bagus ini yang membuatnya jelas setuju dengan gaya fungsional .
sumber
Dalang Pemrograman: Percakapan dengan Pencipta Bahasa Pemrograman Utama
sumber
Jawaban utama adalah bahwa tidak ada yang mau atau harus menggantikan yang lain - mereka adalah alat yang berbeda yang memiliki rangkaian pro dan kontra yang berbeda, dan pendekatan mana yang memiliki keunggulan akan berbeda tergantung pada proyek dan masalah "lunak" lainnya seperti kumpulan bakat yang tersedia.
Saya pikir Anda benar bahwa pertumbuhan konkurensi karena multi-core akan meningkatkan persentase (dari set global proyek pengembangan) ketika pemrograman fungsional dipilih daripada gaya lainnya.
Saya pikir ini langka hari ini karena mayoritas kumpulan bakat profesional saat ini paling nyaman dengan teknologi imperatif dan berorientasi objek. Sebagai contoh, saya memiliki lebih dari satu kali memilih Jawa sebagai bahasa untuk proyek komersial karena itu cukup bagus, tidak kontroversial, dan saya tahu bahwa saya tidak akan pernah kehabisan orang yang dapat memprogram (cukup baik) di dalamnya.
sumber
Terlepas dari keunggulan pemrograman fungsional, pemrograman imperatif dan berorientasi objek tidak akan pernah hilang sepenuhnya.
Pemrograman imperatif dan berorientasi objek adalah deskripsi langkah-demi-langkah dari masalah dan solusinya. Dengan demikian, bisa lebih mudah dipahami. Pemrograman fungsional bisa agak tidak jelas.
Pada akhirnya, program yang bermanfaat akan selalu memiliki efek samping (seperti memberikan keluaran aktual kepada pengguna untuk konsumsi), sehingga bahasa fungsional yang paling murni masih membutuhkan cara untuk masuk ke dunia imperatif dari waktu ke waktu.
Keadaan terkini adalah bahwa bahasa imperatif (seperti C #) meminjam fitur dari dunia fungsional (seperti pernyataan lambda) dan sebaliknya.
sumber
Bukan?
Smalltalk adalah sistem berorientasi objek yang hebat pada masa itu. Mengapa pemrograman berorientasi objek tidak mengambil alih? Ya sudah. Itu tidak terlihat seperti Smalltalk. Bahasa arus utama terus menjadi lebih seperti Smalltalk dengan C ++, Java, C #, dll. Mode dan gaya berubah lebih lambat dari apa pun, jadi ketika OO menjadi arus utama, kami mendapatkannya dengan menempelkan bagian OO ke bahasa lama sehingga cukup mirip seperti C untuk menelan .
Fungsional dengan cara yang sama. Haskell adalah bahasa fungsional yang bagus. Tetapi kami memiliki lebih banyak lagi pemrogram utama yang menggunakan sintaksis mirip-C hari ini dibandingkan 20 tahun yang lalu. Jadi itu harus terlihat seperti C. Selesai: lihat ekspresi LINQ dan katakan itu tidak berfungsi.
sumber
dynamic
. Itulah fitur Smalltalk-y yang paling banyak, jadi tidak mengherankan bagi saya bahwa fitur ini hanya hadir dalam versi terbaru dari yang paling modern dari ketiga bahasa ini. :-)Saya percaya bahwa bahasa imperatif lebih lazim hanya karena itulah yang lebih banyak digunakan orang. Baik pemrograman fungsional maupun model pemrograman imperatif lebih tidak jelas atau akademis daripada yang lain. Bahkan, mereka adalah pelengkap.
Salah satu poster mengatakan bahwa kode imperatif lebih mudah dipahami daripada kode pemrograman fungsional. Ini hanya benar jika pembaca sudah melihat kode imperatif, terutama jika contoh sebelumnya adalah bagian dari "keluarga" yang sama (misalnya, C / C ++, Perl, PHP dan Jawa). Saya tidak akan mengklaim bahwa itu benar untuk bahasa imperatif apa pun ; ambil perbandingan Java dan Forth, untuk membuat contoh ekstrem.
Untuk orang awam, semua bahasa pemrograman adalah omong kosong yang tidak dapat dipahami, kecuali mungkin bahasa verbose seperti Hypertalk dan SQL. (Dari catatan, SQL adalah bahasa deklaratif dan / atau fungsional dan menikmati popularitas luar biasa.)
Jika kita awalnya dilatih bahasa Lisp-y atau Haskell-y sejak awal, kita semua akan berpikir bahasa pemrograman fungsional adalah hal yang normal.
sumber
Anda sudah mendapat cukup jawaban sehingga saya hanya akan menyebutkan beberapa hal yang belum saya lihat disebutkan.
Pertama dan (dalam pikiran saya), bahasa prosedural sangat diuntungkan dari tingkat kesamaannya. Sebagai contoh, hampir semua orang yang tahu hampir semua bahasa prosedural arus utama (atau OO) pada tingkat apa pun dapat membaca sebagian besar bahasa lainnya dengan cukup baik. Saya secara aktif menghindari bekerja di Jawa, C #, Cobol, Fortran, atau Basic (hanya untuk beberapa contoh) tetapi dapat membaca salah satu dari mereka dengan cukup baik - hampir juga, pada kenyataannya, sebagai orang yang menggunakannya setiap hari.
Di sisi fungsional, itu jauh kurang benar. Sebagai contoh, saya dapat menulis Skema dengan cukup masuk akal juga, tetapi itu sedikit berguna dalam membaca Ocaml atau Haskell (hanya untuk beberapa contoh). Bahkan di dalam satu keluarga (misalnya, Skema vs., Common Lisp) keakraban dengan satu tampaknya tidak menerjemahkan hampir juga ke yang lain.
Klaim bahwa kode fungsional lebih mudah dibaca cenderung benar hanya di bawah kondisi yang sempit. Untuk orang-orang yang sangat terbiasa dengan bahasa tersebut, keterbacaan memang luar biasa - tetapi bagi semua orang, ini sering tidak ada. Lebih buruk, sementara perbedaan dalam bahasa prosedural sebagian besar sintaksis dan karena itu relatif mudah dipelajari, perbedaan dalam bahasa fungsional seringkali jauh lebih mendasar, sehingga mereka memerlukan studi yang cukup besar untuk benar-benar memahami (misalnya, mengetahui Lisp sedikit membantu dalam memahami Monads).
Poin utama lainnya adalah bahwa gagasan bahwa program fungsional lebih pendek daripada yang prosedural seringkali lebih didasarkan pada sintaksis daripada semantik. Program yang ditulis dalam Haskell (misalnya) seringkali cukup pendek, tetapi fungsionalnya adalah bagian yang agak kecil. Banyak jika Haskell memiliki sintaksis yang relatif singkat.
Beberapa bahasa murni fungsional dapat bersaing dengan baik dengan APL untuk kode sumber terse (meskipun, dalam keadilan, APL mendukung pembuatan fungsi tingkat yang lebih tinggi juga, sehingga tidak ada perbedaan yang cukup besar seperti dalam beberapa kasus lain). Sebaliknya, Ada dan C ++ (hanya beberapa contoh) bisa sangat kompetitif dalam hal jumlah operasi yang diperlukan untuk menyelesaikan tugas yang diberikan, tetapi sintaksnya (setidaknya biasanya) secara substansial lebih bertele-tele.
sumber
Tidak Perlu Persepsi
Saya ingat tanggapan Bos tua saya Rick Cline ketika saya menunjukkan kepadanya salinan ceramah John Backus 'Turing Award berjudul Dapatkah Pemrograman Dibebaskan dari Gaya von Neumann?
Jawabannya: "Mungkin sebagian dari kita tidak ingin dibebaskan dari gaya von Neumann!"
sumber
Fungsional lebih baik untuk beberapa hal dan lebih buruk untuk orang lain sehingga tidak akan pernah "mengambil alih". Ini sudah ada di mana-mana di dunia nyata.
Program stateless lebih mudah diuji. Ini sekarang dihargai secara luas dan sering dieksploitasi dalam industri.
Anda sedang menggabungkan konkurensi dan paralelisme.
Konkurensi dapat dilakukan secara efektif menggunakan proses sekuensial berkomunikasi (CSP). Kode di dalam CSP dapat mengubah keadaan lokalnya tetapi pesan yang dikirim di antara mereka harus selalu tidak berubah.
Pemrograman yang benar-benar fungsional berfungsi sangat buruk dengan multicore karena itu sangat tidak ramah. Cores akhirnya bersaing untuk memori bersama dan program paralel tidak berskala.
Scala sering dianggap sebagai bahasa fungsional tetapi tidak lebih fungsional daripada C # yang merupakan salah satu bahasa paling populer di dunia saat ini.
Pemrograman yang murni fungsional memiliki banyak kelemahan serius sehingga kami menggunakan bahasa fungsional yang tidak murni seperti Lisp, Skema, SML, OCaml, Scala, dan C #.
sumber
Ketika saya berpikir tentang apa pemrograman fungsional mungkin membawa proyek-proyek saya di tempat kerja saya selalu mengarah pada jalan pemikiran yang sama:
Untuk mendapatkan manfaat penuh dari pemrograman fungsional, Anda perlu kemalasan. Ya, ada bahasa fungsional yang ketat, tetapi manfaat nyata pemrograman fungsional tidak bersinar juga dalam kode yang ketat. Misalnya, di Haskell mudah untuk membuat urutan operasi malas pada daftar dan menggabungkannya dan menerapkannya ke daftar. Misalnya.
op1 $ op2 $ op3 $ op4 $ someList
. Saya tahu bahwa itu tidak akan membangun seluruh daftar dan secara internal saya hanya akan mendapatkan loop bagus yang berjalan melalui elemen satu per satu. Ini memungkinkan Anda untuk menulis kode yang benar-benar modular. Antarmuka antara dua modul dapat melibatkan penyerahan struktur data yang berpotensi besar, namun Anda tidak harus memiliki struktur tersebut.Tetapi ketika Anda mengalami kemalasan, sulit untuk menggunakan memori. Mengubah flag kompilator Haskell sering mengubah jumlah memori yang digunakan oleh suatu algoritma dari O (N) ke O (1), kecuali kadang-kadang tidak. Ini tidak benar-benar dapat diterima ketika Anda memiliki aplikasi yang perlu menggunakan semua memori yang tersedia secara maksimal, dan itu tidak bagus bahkan untuk aplikasi yang tidak membutuhkan semua memori.
sumber
Dua hal:
sumber