Apakah belajar bahasa fungsional membuat programmer OOP lebih baik? [Tutup]

28

Sebagai programmer Java / C # / C ++ saya mendengar banyak pembicaraan tentang bahasa fungsional, tetapi belum pernah menemukan kebutuhan untuk mempelajarinya. Saya juga mendengar bahwa tingkat pemikiran yang lebih tinggi yang diperkenalkan dalam bahasa fungsional membuat Anda menjadi OOP / programmer bahasa prosedural yang lebih baik.

Adakah yang bisa mengkonfirmasi ini? Dengan cara apa itu meningkatkan keterampilan pemrograman Anda?

Apa pilihan bahasa yang baik untuk dipelajari dengan tujuan meningkatkan keterampilan dalam bahasa yang kurang canggih?

Selamat
sumber
3
Jika Anda mengkode dalam C #, Anda sudah tahu satu. LINQ adalah hal yang cukup fungsional.
SK-logic
Saya pikir OOP lebih baik untuk memodelkan objek kehidupan nyata.
Tulains Córdova
1
@ user61852 Kebanyakan pola desain OO tidak memodelkan apa pun tentang objek "kehidupan nyata", tetapi sebenarnya konsep yang sangat abstrak.
Andres F.
Lebih dari sekadar programmer Java / C # (+ C ++). Ada perbedaan antara pisau tentara swiss raksasa dengan pamflet yang tidak terlalu kecil yang menguraikan mengapa Anda akan memilih pisau X dari 40 dan pisau yang bisa Anda pahat di dekat benda apa pun yang Anda sukai karena keduanya sangat tajam dan kurva hanya benar sehingga Anda dapat menerapkannya memotong daya ke berbagai keadaan tanpa banyak pemikiran. (dengan pembuka botol di pegangan saja)
Erik Reppen

Jawaban:

32

Saya pada dasarnya setuju dengan jawaban FrustratedWithFormsDesign , tetapi Anda juga bertanya bagaimana mempelajari paradigma baru membantu mengembangkan keterampilan seseorang. Saya bisa memberikan beberapa contoh dari pengalaman saya sendiri.

Sejak belajar pemrograman fungsional, saya jauh lebih sadar tentang konsep mana yang saya kerjakan lebih alami dianggap sebagai "objek" (umumnya di mana mutasi masuk akal) dan yang lebih alami dianggap sebagai "nilai" yang tidak berubah (saya pikir ada perbedaan penting , menyentuh di mana OO masuk akal vs ketika FP masuk akal, tapi itu hanya pendapat saya).

Saya perhatikan di mana kode saya termasuk efek samping, dan saya lebih berhati-hati untuk mengisolasi tempat-tempat itu, membuat lebih banyak fungsi saya fungsi "murni". Ini sangat meningkatkan testabilitas kode OO saya.

Saya lebih sadar tentang siklus dalam representasi data saya. (Misalnya, saya tidak berpikir Anda dapat menulis fungsi untuk mengubah daftar yang ditautkan menjadi daftar yang ditautkan ganda di Haskell, jadi Anda melihat siklus lebih banyak dalam bahasa itu.) Menghindari siklus mengurangi jumlah sinkronisasi Anda perlu melakukan agar struktur data Anda konsisten secara internal, meringankan beban dalam berbagi struktur ini di antara utas.

Saya lebih cenderung mengandalkan rekursi (konstruksi perulangan rekursif skema adalah hal-hal yang indah). Dijkstra menyinggung tentang pentingnya hal ini dalam Catatan tentang Pemrograman Terstruktur - algoritma rekursif memetakan secara langsung ke induksi matematika, yang ia sarankan adalah satu-satunya cara untuk membuktikan secara intelektual loop-loop kita dengan benar. (Saya tidak menyarankan bahwa kita harus membuktikan kode kita benar, tetapi bahwa semakin mudah kita membuatnya untuk diri kita sendiri, semakin besar kemungkinan kode kita benar.)

Saya lebih cenderung menggunakan fungsi tingkat tinggi. Makalah John Hughes, Mengapa Masalah Program Fungsional . Ini menekankan kompabilitas yang Anda dapatkan dari menggunakan teknik pemrograman fungsional, fungsi tingkat tinggi memainkan peran utama.

Juga, seperti yang disinggung dalam jawaban Jetti , Anda akan menemukan bahwa banyak ide KB dimasukkan ke dalam bahasa OO yang lebih baru. Ruby dan Python keduanya menyediakan banyak fungsi tingkat tinggi, saya pernah mendengar LINQ digambarkan sebagai upaya untuk membawa dukungan untuk pemahaman monadik ke dalam C #, bahkan C ++ sekarang memiliki ekspresi lambda.

Aidan Cully
sumber
@ Aidan: wrt lambdas di C ++ 0x, bagaimanapun kompiler C ++ baru telah memasukkannya.
Matthieu M.
1
"Objek" sebagai "benda yang memiliki status dapat berubah" sangat umum, tetapi pola Nilai Objek sudah ada selama bertahun-tahun.
Frank Shearar
@ Matthieu, terima kasih, saya telah memperbarui teks untuk mencerminkannya.
Aidan Cully
@ Frank: terima kasih atas penunjuknya. Saya tidak memasukkan ini dalam jawaban, tetapi keberatan utama saya harus membuat Nilai menjadi Objek ada hubungannya dengan perbedaan b / w antarmuka objek (yang dimiliki oleh objek) dan operasi (di mana hubungan antara objek lebih primer dari objek itu sendiri). 1 + 2secara matematis setara dengan 2 + 1, tetapi 1.+(2)diimplementasikan secara berbeda dari 2.+(1). Ada sejumlah masalah SW yang dapat dipahami secara lebih alami menggunakan operasi daripada menggunakan antarmuka objek.
Aidan Cully
1
@ Aidan Sudahkah Anda membaca buku William Cook's "On Understanding Abstraction, Revisited"? Ini menggali perbedaan antara objek dan ADT, yang adalah apa yang Anda mengisyaratkan.
Frank Shearar
32

Saya tidak akan mengatakan itu dijamin untuk membuat Anda seorang programmer OOP yang lebih baik, tetapi itu akan memperkenalkan Anda pada cara berpikir yang baru, dan itu bisa membuat Anda lebih baik dalam pemecahan masalah secara umum, bukan hanya dalam hal OOP.

FrustratedWithFormsDesigner
sumber
3
Mengingat bahwa objek sebenarnya adalah fungsi-fungsi tingkat tinggi, saya menemukan bahwa mempelajari hal-hal FP memang membantu secara langsung dengan OOP saya. Namun, seperti yang Anda katakan, lebih umum berlaku / bermanfaat.
Frank Shearar
12

Mempelajari bahasa fungsional - Lisp for me - sangat membantu saat membangun aplikasi paralel. Metode fungsional (berbasis negara, tanpa efek samping) jauh lebih mudah disinkronkan, dan lebih mudah untuk membuat utas aman karena hanya bergantung pada inputnya. Itu berarti satu-satunya data yang Anda perlu perhatikan untuk area kode tertentu adalah parameter yang Anda berikan. Ini juga memudahkan untuk debug.

Michael K.
sumber
Anda akan menemukannya juga membantu dengan threading libraries, yang cenderung mengharapkan fungsi murni sebagai tugas mereka. Ini juga dapat membantu secara tidak langsung, ada tempat di mana saya akan menulis kode OO dalam semacam "gaya fungsional" di mana ada "parameter yang memiliki" yang memiliki kunci implisit pada banyak objek yang dirujuk dan digunakan oleh fungsi . Selama Anda mendokumentasikan harapan Anda (dan unit mengujinya) ini dapat memberi Anda kode multithreaded yang lebih baik dengan beberapa masalah penguncian. Dan beberapa kunci eksplisit.
Saya tidak pernah mendengar Prolog disebut sebagai bahasa fungsional. Jika saya cukup menyipitkan mata saya samar-samar dapat melihat bagaimana (bagian) Prolog dapat membantu dengan FP.
Frank Shearar
1
Prolog bukan bahasa fungsional. Itu bahasa logika. Jika Anda menginginkan bahasa logika mirip Prolog yang juga mengintegrasikan pemrograman fungsional, ingatlah, Anda bisa melihat Mercury . Peringatan: Ini akan sedikit melukai otak Anda bahkan jika Anda sudah tahu Prolog.
HANYA SAYA PENDAPAT yang benar
@ HANYA PENDAPATAN SAYA yang benar: Ya, saya pikir Anda benar. Tebak saya perlu belajar lebih banyak tentang bahasa fungsional!
Michael K
1
@moz: Ya, saya berharap Jawa memiliki lambdas. ThreadObjek anonim adalah ... canggung.
Michael K
9

Belajar setiap paradigma lain dari pemrograman akan meningkatkan kemampuan pemrograman Anda secara umum. Pemrograman, ketika itu bukan hal-hal kelas penelitian akademik (dan bahkan kemudian, sering), pada dasarnya adalah pemecahan masalah. Berpikir, dalam satu kata. Berbagai paradigma adalah cara berpikir yang berbeda tentang masalah dan solusinya. Jadi jangan hanya menganggapnya sebagai "belajar bahasa fungsional". Anggap saja "mempelajari cara berbeda untuk memikirkan masalah dan solusinya". Maka Anda akan melihat manfaat dari belajar bahasa meskipun Anda tidak pernah menggunakannya.

Untuk menjawab pertanyaan spesifik Anda, saya adalah seorang programmer C ++ pada zaman dahulu (dulu sebelum ada standar untuk C ++). Saya mengikuti semua hal yang biasa dengan benda-benda memegang keadaan dimanipulasi oleh metode, dll. Dll. Kemudian saya menemukan Haskell dan belajar (banyak) itu. (Saya tidak berpikir ada orang yang benar-benar belajar Haskell.) Latihan itu tampak agak sia-sia pada saat itu sampai salah satu kolega saya, penguji yang ditugaskan untuk kelompok saya, berkomentar sambil lalu bahwa kode saya semakin mudah untuk diuji.

Apa yang terjadi adalah saya mulai membuat objek saya semakin abadi. Kelas dengan keadaan berubah-ubah kompleks mulai diganti dengan kelas yang mengkloning diri mereka sendiri dengan perubahan, mengembalikan objek baru. Objek bersama mulai diganti dengan objek yang memiliki semantik copy-on-write (sehingga memberikan ilusi banyak klon objek tanpa overhead memori). Functions tidak memiliki efek samping kecuali benar-benar diperlukan; definisi "fungsi" yang murni dan matematis semakin banyak menjadi norma. Semua ini mulai terjadi dalam kode saya secara alami - tidak ada pemikiran sadar yang terlibat - ketika saya menjelajahi semakin banyak ruang pemrograman fungsional.

Sekarang saya menjadikannya tujuan untuk mempelajari setidaknya satu paradigma pemrograman baru setiap dua tahun (bahkan jika itu hanya paradigma ekstensi kecil seperti AOP) dan setidaknya dua bahasa baru dalam setiap paradigma (satu semurni mungkin, satu hibrida / praktis ). Masing-masing telah memberi saya alat intelektual baru untuk diterapkan ke semua pemrograman saya dalam bahasa apa pun, sehingga waktu yang dihabiskan untuk mempelajarinya, menurut saya, bahkan sedikit terbuang.

HANYA PENDAPAT SAYA yang benar
sumber
3

Saya sudah mengatakannya sebelumnya dan saya akan mengatakannya lagi, belajar bahasa fungsional pasti meningkatkan C # saya. Itu membantu saya memahami lambdas (dan membantu saya mencintai mereka). Itu juga membuat saya menyadari betapa saya lebih suka pemrograman fungsional (F #) ketika bekerja dengan operasi Asynchronous!

Jetti
sumber
3

Kode mesin tidak lebih dari daftar efek samping - perintah yang langsung dijalankan oleh prosesor. Efek samping dalam C berbeda, daripada menangani register dan perangkat keras fisik, Anda berurusan dengan serangkaian abstraksi dan membiarkan kompilator melakukan semua pekerjaan kotor. C juga memungkinkan Anda menyusun efek samping dalam loop dan pernyataan if. C ++ meningkat pada C dengan menambahkan OOP dan beberapa fitur yang sangat dibutuhkan untuk bahasa. Java dan C # menambahkan pengumpulan sampah, dan Python menambahkan pengetikan dinamis.

Bahkan dengan semua fitur ini - pengetikan dinamis, pengumpulan sampah, dll program dalam bahasa ini masih sepenuhnya didasarkan pada efek samping. Bahasa pemrograman fungsional, seperti Skema, Clojure, Haskell, dan ML adalah sesuatu yang sama sekali berbeda, bahasa-bahasa ini lebih dekat dengan matematika daripada kode mesin. Alih-alih menggunakan efek samping Anda memberikan nilai sekitar fungsi.

Apa pilihan bahasa yang baik untuk dipelajari dengan tujuan meningkatkan keterampilan dalam bahasa yang kurang canggih?

Saya merekomendasikan Skema , ini minimal dan digunakan di kelas pemrograman lama MIT. Bahasa pemrograman fungsional lainnya jauh lebih sulit untuk dipelajari. Clojure membawa semua seluk-beluk Jawa dengan itu, ML membawa serta sistem tipe statis yang rumit, Haskell kadang-kadang disebut sebagai bahasa akademik - tidak ideal untuk pemula, dan sebagainya. Skema di sisi lain mudah dipelajari dan dipahami.

Dengan cara apa itu meningkatkan keterampilan pemrograman Anda?

Hampir semua bahasa pemrograman tingkat tinggi memiliki fungsi dan rekursi - konsep yang menjadi dasar pemrograman fungsional. Dengan demikian, pengetahuan Anda tentang FP harus membantu hampir di semua tempat, namun, jika Anda benar-benar ingin memprogram secara fungsional, Anda harus menggunakan bahasa yang lebih alami dan efisien daripada mencoba membengkokkan desain bahasa orang lain sesuai dengan keinginan Anda, yaitu Anda harus menggunakan bahasa pemrograman fungsional untuk melakukan pemrograman fungsional.

jhuni
sumber