Sebagian besar bahasa arus utama, termasuk bahasa pemrograman berorientasi objek (OOP) seperti C #, Visual Basic, C ++, dan Java dirancang untuk terutama mendukung pemrograman imperatif (prosedural), sedangkan bahasa Haskell / gofer seperti murni berfungsi. Adakah yang bisa menguraikan apa perbedaan antara kedua cara pemrograman ini?
Saya tahu itu tergantung pada kebutuhan pengguna untuk memilih cara pemrograman tetapi mengapa dianjurkan untuk belajar bahasa pemrograman fungsional?
oop
functional-programming
Swapnil Kotwal
sumber
sumber
Jawaban:
Definisi: Bahasa imperatif menggunakan urutan pernyataan untuk menentukan cara mencapai tujuan tertentu. Pernyataan-pernyataan ini dikatakan mengubah keadaan program karena masing-masing dieksekusi pada gilirannya.
Contoh: Java adalah bahasa imperatif. Misalnya, sebuah program dapat dibuat untuk menambahkan serangkaian angka:
Setiap pernyataan mengubah status program, dari menetapkan nilai ke setiap variabel hingga penambahan akhir dari nilai-nilai tersebut. Dengan menggunakan urutan lima pernyataan, program secara eksplisit diberitahu cara menambahkan angka 5, 10 dan 15 bersama-sama.
Bahasa fungsional: Paradigma pemrograman fungsional secara eksplisit dibuat untuk mendukung pendekatan fungsional murni untuk pemecahan masalah. Pemrograman fungsional adalah bentuk pemrograman deklaratif.
Keuntungan Fungsi Murni: Alasan utama untuk menerapkan transformasi fungsional sebagai fungsi murni adalah bahwa fungsi murni dapat dikomposisikan: yaitu mandiri dan tanpa kewarganegaraan. Karakteristik ini membawa sejumlah manfaat, termasuk yang berikut: Peningkatan keterbacaan dan pemeliharaan. Ini karena setiap fungsi dirancang untuk menyelesaikan tugas tertentu mengingat argumennya. Fungsi ini tidak bergantung pada kondisi eksternal apa pun.
Perkembangan pengulangan yang lebih mudah. Karena kode lebih mudah direvisi, perubahan desain sering kali lebih mudah diterapkan. Misalnya, Anda menulis transformasi yang rumit, dan kemudian menyadari bahwa beberapa kode diulang beberapa kali dalam transformasi. Jika Anda refactor melalui metode murni, Anda dapat memanggil metode murni sesuka hati tanpa khawatir tentang efek samping.
Pengujian dan debugging yang lebih mudah. Karena fungsi murni dapat lebih mudah diuji secara terpisah, Anda dapat menulis kode uji yang memanggil fungsi murni dengan nilai tipikal, case edge yang valid, dan case edge yang tidak valid.
Untuk Orang OOP atau bahasa Imperatif:
Bahasa berorientasi objek baik ketika Anda memiliki serangkaian operasi pada hal-hal dan ketika kode Anda berkembang, Anda terutama menambahkan hal-hal baru. Ini dapat dicapai dengan menambahkan kelas baru yang menerapkan metode yang ada dan kelas yang ada dibiarkan sendiri.
Bahasa fungsional baik ketika Anda memiliki satu set hal yang tetap dan ketika kode Anda berkembang, Anda terutama menambahkan operasi baru pada hal-hal yang ada. Ini dapat dicapai dengan menambahkan fungsi baru yang menghitung dengan tipe data yang ada dan fungsi yang ada dibiarkan sendiri.
Cons:
Itu tergantung pada persyaratan pengguna untuk memilih cara pemrograman, sehingga ada salahnya hanya ketika pengguna tidak memilih cara yang tepat.
Ketika evolusi salah jalan, Anda memiliki masalah:
sumber
Inilah perbedaannya:
Imperatif:
... dan seterusnya dan seterusnya ...
Deklaratif, sedangkan fungsional adalah subkategori:
... dan seterusnya dan seterusnya ...
Rangkuman: Dalam bahasa imperatif Anda memberi tahu komputer cara mengubah bit, byte, dan kata-kata dalam memori itu dan dalam urutan apa. Dalam fungsional, kami memberi tahu komputer apa hal, tindakan, dll. Sebagai contoh, kita katakan bahwa faktorial 0 adalah 1, dan faktorial dari setiap bilangan alami lainnya adalah produk dari angka tersebut dan faktorial dari pendahulunya. Kita tidak mengatakan: Untuk menghitung faktorial dari n, cadangan wilayah memori dan simpan 1 di sana, lalu gandakan angka di wilayah memori itu dengan angka 2 ke n dan simpan hasilnya di tempat yang sama, dan pada akhirnya, wilayah memori akan berisi faktorial.
sumber
Sebagian besar bahasa modern memiliki tingkat imperatif dan fungsional yang bervariasi tetapi untuk lebih memahami pemrograman fungsional, akan lebih baik untuk mengambil contoh bahasa fungsional murni seperti Haskell dalam kontras kode imperatif dalam bahasa yang tidak begitu fungsional seperti java / c #. Saya percaya itu selalu mudah untuk dijelaskan dengan contoh, jadi di bawah ini adalah satu.
Pemrograman fungsional: menghitung faktorial n yaitu n! yaitu nx (n-1) x (n-2) x ... x 2 X 1
Perhatikan bahwa Haskel memungkinkan overloading fungsi ke tingkat nilai argumen. Sekarang di bawah ini adalah contoh kode imperatif dalam meningkatkan tingkat imperativeness:
Bacaan ini bisa menjadi referensi yang baik untuk memahami bahwa bagaimana kode imperatif lebih fokus pada bagaimana bagian, keadaan mesin (i in for loop), urutan eksekusi, flow control.
Contoh selanjutnya dapat dilihat sebagai kode java / c # lang secara kasar dan bagian pertama sebagai batasan bahasa itu sendiri berbeda dengan Haskell untuk membebani fungsi dengan nilai (nol) dan karenanya dapat dikatakan itu bukan bahasa fungsional murni, di sisi lain tangan Anda dapat mengatakan itu mendukung prog fungsional. sampai batas tertentu.
Pengungkapan: tidak ada kode di atas yang diuji / dieksekusi tetapi mudah-mudahan harus cukup baik untuk menyampaikan konsep; juga saya sangat menghargai komentar untuk koreksi seperti itu :)
sumber
return n * factorial(n-1);
?n * (n-1)
Pemrograman Fungsional adalah bentuk pemrograman deklaratif, yang menggambarkan logika perhitungan dan urutan eksekusi sepenuhnya tidak ditekankan.
Masalah: Saya ingin mengubah makhluk ini dari kuda menjadi jerapah.
Setiap item dapat dijalankan dalam urutan apa pun untuk menghasilkan hasil yang sama.
Pemrograman Imperatif bersifat prosedural. Negara dan ketertiban itu penting.
Masalah: Saya ingin memarkir mobil saya.
Setiap langkah harus dilakukan untuk mencapai hasil yang diinginkan. Menarik ke garasi saat pintu garasi ditutup akan menghasilkan pintu garasi yang rusak.
sumber
Pemrograman fungsional adalah "pemrograman dengan fungsi," di mana suatu fungsi memiliki beberapa sifat matematika yang diharapkan, termasuk transparansi referensial. Dari sifat-sifat ini, sifat-sifat selanjutnya mengalir, khususnya langkah-langkah penalaran akrab yang dimungkinkan oleh substitusi yang mengarah pada bukti matematis (yaitu membenarkan kepercayaan pada hasil).
Oleh karena itu program fungsional hanyalah ekspresi.
Anda dapat dengan mudah melihat kontras antara kedua gaya dengan mencatat tempat-tempat dalam program imperatif di mana ekspresi tidak lagi transparan secara referensial (dan karena itu tidak dibangun dengan fungsi dan nilai, dan tidak dapat dengan sendirinya menjadi bagian dari fungsi). Dua tempat yang paling jelas adalah: mutasi (misalnya variabel) efek samping lain aliran kontrol non-lokal (misalnya pengecualian)
Pada kerangka kerja program-sebagai-ekspresi yang terdiri dari fungsi dan nilai-nilai ini, dibangun paradigma praktis seluruh bahasa, konsep, "pola fungsional", kombinator, dan berbagai jenis sistem dan algoritma evaluasi.
Dengan definisi paling ekstrem, hampir semua bahasa — bahkan C atau Java — dapat disebut fungsional, tetapi biasanya orang mencadangkan istilah untuk bahasa dengan abstraksi yang relevan secara spesifik (seperti penutupan, nilai yang tidak dapat diubah, dan alat bantu sintaksis seperti pencocokan pola). Sejauh penggunaan pemrograman fungsional menyangkut itu melibatkan penggunaan functins dan membangun kode tanpa efek samping. digunakan untuk menulis bukti
sumber
Gaya pemrograman imperatif dipraktikkan dalam pengembangan web dari tahun 2005 hingga 2013.
Dengan pemrograman imperatif, kami menulis kode yang mencantumkan apa yang seharusnya dilakukan aplikasi kami, langkah demi langkah.
Gaya pemrograman fungsional menghasilkan abstraksi melalui cara pintar menggabungkan fungsi.
Ada disebutkan pemrograman deklaratif dalam jawaban dan mengenai hal itu saya akan mengatakan bahwa pemrograman deklaratif mencantumkan beberapa aturan yang harus kita ikuti. Kami kemudian memberikan apa yang kami sebut sebagai beberapa kondisi awal untuk aplikasi kami dan kami membiarkan aturan-aturan semacam itu mendefinisikan bagaimana aplikasi itu berlaku.
Sekarang, deskripsi singkat ini mungkin tidak masuk akal, jadi mari kita melihat perbedaan antara pemrograman imperatif dan deklaratif dengan menelusuri analogi.
Bayangkan kita tidak membangun perangkat lunak, tetapi kita membuat kue untuk mencari nafkah. Mungkin kita adalah tukang roti yang buruk dan tidak tahu cara membuat kue yang lezat seperti yang seharusnya.
Jadi bos kita memberi kita daftar arah, apa yang kita ketahui sebagai resep.
Resepnya akan memberi tahu kami cara membuat pai. Satu resep ditulis dengan gaya imperatif seperti:
Resep deklaratif akan melakukan hal berikut:
1 cangkir tepung, 1 telur, 1 cangkir gula - keadaan awal
Aturan
Jadi pendekatan imperatif ditandai dengan pendekatan langkah demi langkah. Anda mulai dengan langkah pertama dan lanjutkan ke langkah 2 dan seterusnya.
Anda akhirnya berakhir dengan beberapa produk akhir. Jadi membuat pai ini, kami mengambil bahan-bahan ini mencampurnya, menaruhnya di dalam panci dan di oven dan Anda mendapatkan produk akhir Anda.
Dalam dunia deklaratif, ini berbeda. Dalam resep deklaratif kita akan memisahkan resep kita menjadi dua bagian yang terpisah, mulai dengan satu bagian yang mencantumkan status awal resep, seperti variabel. Jadi variabel kami di sini adalah jumlah bahan dan jenisnya.
Kami mengambil kondisi awal atau bahan awal dan menerapkan beberapa aturan padanya.
Jadi kita mengambil kondisi awal dan melewati mereka melalui aturan ini berulang-ulang sampai kita siap untuk makan pai stroberi rhubarb atau apa pun.
Jadi, dalam pendekatan deklaratif, kita harus tahu cara menyusun aturan ini dengan benar.
Jadi aturan yang kita mungkin ingin memeriksa bahan atau negara kita, jika dicampur, masukkan ke dalam panci.
Dengan keadaan awal kami, itu tidak cocok karena kami belum mencampur bahan kami.
Jadi aturan 2 mengatakan, jika tidak tercampur maka campurlah dalam mangkuk. Oke ya aturan ini berlaku.
Sekarang kami memiliki semangkuk bahan campuran sebagai keadaan kami.
Sekarang kita menerapkan negara baru itu ke aturan kita lagi.
Jadi aturan 1 mengatakan jika bahan dicampur tempatkan mereka dalam panci, oke ya sekarang aturan 1 berlaku, mari kita lakukan.
Sekarang kita memiliki keadaan baru ini di mana bahan dicampur dan dalam wajan. Aturan 1 tidak lagi relevan, aturan 2 tidak berlaku.
Aturan 3 mengatakan jika bahan-bahannya ada di dalam wajan, letakkan di dalam oven, bagus aturan yang berlaku untuk keadaan baru ini, mari kita lakukan.
Dan kita berakhir dengan pai apel panas yang lezat atau apa pun.
Sekarang, jika Anda seperti saya, Anda mungkin berpikir, mengapa kita tidak melakukan pemrograman imperatif. Ini masuk akal.
Ya, untuk aliran sederhana ya, tetapi sebagian besar aplikasi web memiliki aliran lebih kompleks yang tidak dapat ditangkap dengan baik oleh desain pemrograman imperatif.
Dalam pendekatan deklaratif, kita mungkin memiliki beberapa bahan awal atau keadaan awal seperti
textInput=“”
, variabel tunggal.Mungkin input teks dimulai sebagai string kosong.
Kami mengambil status awal ini dan menerapkannya pada seperangkat aturan yang ditentukan dalam aplikasi Anda.
Jika pengguna memasukkan teks, perbarui input teks. Ya, sekarang itu tidak berlaku.
Jika template diberikan, hitung widget.
Yah, semua ini tidak berlaku sehingga program hanya akan menunggu sebuah peristiwa terjadi.
Jadi pada titik tertentu pengguna memperbarui input teks dan kemudian kita mungkin menerapkan aturan nomor 1.
Kami dapat memperbarui itu ke
“abcd”
Jadi kami baru saja memperbarui pembaruan teks dan input teks, aturan nomor 2 tidak berlaku, aturan nomor 3 mengatakan jika input teks diperbarui, yang baru saja terjadi, lalu render ulang templat, lalu kami kembali ke aturan 2 yang mengatakan jika templat diberikan , hitung widgetnya, oke mari kita hitung widgetnya.
Secara umum, sebagai programmer, kami ingin mengusahakan desain pemrograman yang lebih deklaratif.
Imperatif tampak lebih jelas dan jelas, tetapi pendekatan deklaratif berskala sangat baik untuk aplikasi yang lebih besar.
sumber
• Bahasa Imperatif:
Eksekusi yang efisien
Semantik yang kompleks
Sintaks yang kompleks
Concurrency dirancang oleh programmer
Pengujian kompleks, tidak memiliki transparansi referensial, memiliki efek samping
• Bahasa Fungsional:
Semantik sederhana
Sintaks sederhana
Eksekusi kurang efisien
Program dapat dibuat secara bersamaan
Pengujian sederhana, memiliki transparansi referensial, tidak memiliki efek samping
sumber
Saya pikir itu mungkin untuk mengekspresikan pemrograman fungsional dengan cara imperatif:
if... else
/switch
pernyataanAda masalah besar dengan pendekatan seperti itu:
Pemrograman fungsional, mengobati fungsi / metode seperti objek dan merangkul kewarganegaraan, lahir untuk menyelesaikan masalah yang saya percaya.
Contoh penggunaan: aplikasi frontend seperti Android, iOS atau logika aplikasi web termasuk. komunikasi dengan backend.
Tantangan lain ketika mensimulasikan pemrograman fungsional dengan kode imperatif / prosedural:
Saya juga percaya bahwa pada akhirnya, kode fungsional akan diterjemahkan ke dalam kode perakitan atau mesin yang sangat penting / prosedural oleh kompiler. Namun, kecuali Anda menulis rakitan, sebagai manusia yang menulis kode dengan bahasa tingkat tinggi / dapat dibaca manusia, pemrograman fungsional adalah cara ekspresi yang lebih tepat untuk skenario yang tercantum
sumber
Saya tahu pertanyaan ini lebih lama dan yang lain sudah menjelaskannya dengan baik, saya ingin memberikan contoh masalah yang menjelaskan hal yang sama secara sederhana.
Masalah: Menulis tabel 1's.
Solusi: -
Menurut gaya Imperatif: =>
Menurut gaya Fungsional: =>
Penjelasan dalam gaya Imperatif kami menulis instruksi secara lebih eksplisit dan yang dapat disebut dengan cara yang lebih sederhana.
Sedangkan seperti dalam gaya Fungsional, hal-hal yang jelas akan diabaikan.
sumber