Pemrograman Fungsional vs. OOP [ditutup]

93

Saya telah mendengar banyak pembicaraan tentang penggunaan bahasa fungsional seperti Haskell pada akhir-akhir ini. Apa saja perbedaan besar, pro dan kontra dari pemrograman fungsional vs pemrograman berorientasi objek?

GSto
sumber
27
Seseorang tidak menolak yang lain.
mbq
1
@ MBQ saya mengerti bahwa mereka tidak saling eksklusif, tetapi saya hanya ingin mencoba untuk mendapatkan pemahaman yang lebih baik tentang perbedaan dari dua pendekatan.
GSto
Pertanyaan bagus Saya juga bertanya-tanya tentang hal ini.
JohnFx
Pemrograman fungsional dan pemrograman berorientasi objek saling orthogonal. Anda dapat memiliki keduanya dalam bahasa yang sama. Contoh: Scala, F #, OCaml dll. Mungkin yang Anda maksud fungsional vs imperatif, seperti yang disarankan Jonas ?
missingfaktor
4
Jawaban sebenarnya adalah - tidak ada "lawan" di antara mereka. Lihatlah pertanyaan ini di StackOverflow .
missingfaktor

Jawaban:

67

Saya akan mengatakan bahwa itu lebih Pemrograman Fungsional vs Pemrograman Imperatif .

Perbedaan terbesar adalah bahwa pemrograman Imperatif adalah tentang aliran Kontrol sedangkan pemrograman Fungsional adalah tentang aliran data . Cara lain untuk mengatakannya adalah bahwa pemrograman fungsional hanya menggunakan ekspresi sedangkan dalam pemrograman imperatif baik ekspresi dan pernyataan digunakan.

Sebagai contoh, dalam variabel pemrograman imperatif dan loop adalah umum ketika menangani keadaan, sedangkan dalam pemrograman fungsional negara ditangani melalui parameter yang lewat, yang menghindari efek samping dan tugas.

Kode pseudo imperatif untuk fungsi menghitung jumlah daftar (jumlah disimpan dalam variabel):

int sumList(List<int> list) {
    int sum = 0;
    for(int n = 0; n < list.size(); n++) {
        sum = sum + list.get(n);
    }

    return sum;
}

Kode pseudo fungsional untuk fungsi yang sama (jumlah dilewatkan sebagai parameter):

fun sumList([], sum) = sum
 |  sumList(v::lst, sum) = sumList(lst, v+sum)

Saya merekomendasikan presentasi Efek Menjinakkan dengan Pemrograman Fungsional oleh Simon Peyton-Jones untuk pengenalan yang baik untuk konsep-konsep fungsional.

Jonas
sumber
12
Anda harus menyebutkan bahwa versi fungsionalnya adalah rekursif ekor dan dengan demikian dioptimalkan untuk menghindari stack overflows. (Beberapa orang mungkin melihat rekursi dan berpikir bahwa pemrograman fungsional buruk karena itu)
alternatif
3
+1 untuk menggambarkan aspek terpenting imperatif vs fungsional: aliran kontrol vs aliran data. Satu hal yang harus saya tambahkan adalah bahwa paradigma fungsional dan paradigma OO tidak saling eksklusif; Anda dapat menggunakan paradigma OO untuk memodelkan bagaimana objek (data) berinteraksi, dan paradigma fungsional untuk mengubah (memanipulasi) objek itu.
Lie Ryan
1
Menariknya, Anda dapat memodelkan data-as-control dan control-as-data juga untuk dicampur. FP dapat menggunakan Arrows dan fungsi urutan pertama untuk meneruskan aliran kontrol dan memanipulasinya seperti data. OOP menggunakan berbagai pola desain untuk menggunakan objek untuk mengubah aliran kontrol.
CodexArcanum
Saya pikir itu juga perlu dicatat bahwa perbedaan utama bukanlah bahwa Anda menulis program yang sama tetapi Anda membuat loop Anda memanggil metode recursive. jauh lebih besar dari itu
sara
Contoh fungsional Anda menggunakan pencocokan pola parameter. Itu tidak eksklusif untuk pemrograman fungsional, program fungsional serupa dapat menggunakan monads dan bahkan konstruksi imperatif tanpa perlu merumuskan setiap algoritma iteratif sebagai algoritma rekursif.
Dai
16

Pemrograman fungsional didasarkan pada model deklaratif dan berakar dari kalkulus lambda. Ini menawarkan banyak konsep hebat yang dapat dipinjam dari bahasa yang lebih penting seperti C ++ dan C #.

Beberapa contoh termasuk transparansi referensial, fungsi lambda, fungsi kelas satu, evaluasi malas dan bersemangat, dan kekekalan.

Jika tidak ada yang lain belajar pemrograman fungsional berguna untuk konsep-konsep yang dikandungnya. Ini akan mengubah cara Anda melakukan pemrograman dan berpikir tentang pemrograman. Dan saya akan menebak bahwa di masa depan pemrograman fungsional akan sama pentingnya dengan pemrograman berorientasi objek.

Untuk memulai, Anda dapat memilih untuk menggunakan bahasa fungsional murni seperti Haskell, atau Anda dapat menggunakan bahasa hibrida seperti F # .

Sebagian besar universitas yang bagus akan mencakup pemrograman fungsional dan jika Anda bersekolah, saya sangat menyarankan Anda mengikuti kursus itu.


Apa saja perbedaan besar, pro dan kontra dari pemrograman fungsional vs pemrograman berorientasi objek?

Pemrograman berorientasi objek yang baik bagus karena memungkinkan Anda untuk memodelkan masalah kompleks Anda menjadi hierarki sehingga Anda dapat menyederhanakan masalah. Tapi itu menjadi sangat sulit ketika Anda mulai mempertimbangkan pemrograman multi-threaded saat menggunakan objek yang bisa berubah. Dalam kasus seperti itu Anda perlu menggunakan banyak objek sinkronisasi dan hampir tidak mungkin untuk menyempurnakan aplikasi besar.

Di situlah pemrograman fungsional masuk. Karena hal-hal seperti pemrograman fungsional immutability benar-benar menyederhanakan program multi-threaded. Itu membuatnya hampir sepele mudah untuk memparalelkan sesuatu ketika Anda tahu bahwa diberi input X ke fungsi itu akan selalu menghasilkan Y. Juga Anda tahu bahwa variabel (atau nilai dalam pemrograman fungsional) tidak dapat mengubah penggunaan pertengahan dari utas lainnya.

Brian R. Bondy
sumber
2
Agar jelas, Skema sama sekali bukan bahasa fungsional murni.
Jonathan Sterling
5
Paragraf terakhir kedua Anda sepenuhnya bs. OO tidak menimbulkan masalah dalam multithreading, memang bisa berubah-ubah. Anda tampaknya membingungkan pemrograman imperatif dengan pemrograman berorientasi objek. Apakah itu masalahnya?
missingfaktor
5
@missingfaktor: Tidak, saya tidak membingungkan konsep. Objek biasanya memiliki pengakses, pengubah, anggota data dan fungsi anggota. Ya tidak semua objek perlu memiliki pengubah dan Anda dapat menerapkannya sebagai tidak berubah. Tetapi jika Anda melihat program OO sembarang, hampir pasti akan memiliki beberapa objek yang memiliki pengubah dan masih digunakan oleh multi-threads. Yaitu dalam paradigma OOP, sangat jarang memiliki segalanya yang abadi.
Brian R. Bondy
Anda harus membaca jawaban atas pertanyaan ini: stackoverflow.com/questions/3949618/fp-and-oo-orthogonal/…
missingfaktor
Periksa juga jawaban Frank Shearar di sini: programmers.stackexchange.com/questions/12423/…
missingfaktor
8

(Jawaban ini diadaptasi dari jawaban ke pertanyaan tertutup di StackOverflow .)

Salah satu perbedaan besar antara pemrograman fungsional dan pemrograman berorientasi objek adalah bahwa masing-masing lebih baik pada jenis evolusi perangkat lunak yang berbeda:

  • 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.

Ketika evolusi salah jalan, Anda memiliki masalah:

  • Menambahkan operasi baru ke program berorientasi objek mungkin memerlukan pengeditan banyak definisi kelas untuk menambahkan metode baru.

  • Menambahkan hal baru ke program fungsional mungkin memerlukan pengeditan banyak definisi fungsi untuk menambahkan kasus baru.

Masalah ini telah dikenal selama bertahun-tahun; pada tahun 1998, Phil Wadler menjulukinya "masalah ekspresi" . Meskipun beberapa peneliti berpikir bahwa masalah ekspresi dapat diatasi dengan fitur bahasa seperti mixin, solusi yang diterima secara luas belum mencapai arus utama.

Norman Ramsey
sumber
Saya suka jawaban Anda, kata-kata bijak di sini. Saya bertemu beberapa bulan yang lalu dan hanya menghabiskan 30 menit secara khusus mencarinya karena saya tidak membookmarknya. Hanya penjelasan terbaik tentang OOP vs FP bagi mereka yang memahami keunggulan memahami konsep daripada teknik. Makalah tentang masalah ekspresi juga fantastis. Terima kasih banyak untuk membagikan wawasan Anda, jawaban Anda sangat diremehkan menurut saya.
tobiak777
4

Tidak ada yang nyata versus. Mereka bisa saling melengkapi dengan sempurna. Ada bahasa FP, yang mendukung OOP. Tetapi komunitas berbeda dalam cara mereka menangani modularitas.

Pengguna bahasa FP cenderung mencapai modularitas melalui hukum matematika. Dan lebih suka bukti untuk menunjukkan kepatuhan dengan hukum mereka.

Dalam imperatif OOP pengguna cenderung menangkap perilaku objek dalam kasus-uji, yang dapat dijalankan kembali jika objek telah berubah dan mencapai dengan cara modularitas ini.

Ini hanya aspek kecil, tapi saya pikir itu layak disebutkan.

Edgar Klerks
sumber
2

Sebuah analogi:

Anda menerima lamaran pekerjaan. Anda mengisi nama, informasi kontak, dan riwayat kerja Anda. Setelah selesai, Anda tidak lagi memiliki aplikasi kosong.

Sekarang bayangkan sebaliknya bahwa sebelum menulis Anda melapisinya dengan selofan yang jelas. Anda menulis nama Anda. Anda menambahkan selofan selembar lagi. Anda menulis informasi kontak Anda. Lebih banyak selofan. Anda menulis riwayat kerja Anda. Setelah selesai, Anda masih memiliki aplikasi kosong yang belum tersentuh. Anda juga memiliki tiga lembar selofan yang masing-masing menangkap efek perubahan tunggal yang terpisah.

Yang pertama (OOP) menganut gagasan mengubah hal-hal di tempat sementara yang terakhir (FP) menolaknya. Keduanya adalah paradigma manajemen negara. Keduanya dapat, menggunakan strategi yang berbeda, menangkap efek dari menyelesaikan lamaran kerja. OOP mengubah instrumen awal secara langsung, sementara FP menutupi apa yang terjadi sebelumnya untuk mempengaruhi penampilan perubahan .

Mario T. Lanza
sumber
analogi yang indah, thx !! maukah Anda (jika mungkin) memperluas analogi ini dengan pro dan kontra dalam dua pendekatan ini.
Rahul Agarwal