Apakah Ruby adalah bahasa fungsional?

88

Wikipedia mengatakan Ruby adalah bahasa fungsional, tetapi saya tidak yakin. Mengapa atau mengapa tidak?

Esteban Araya
sumber
4
Mungkin karena pertanyaan Anda sangat singkat, meskipun secara pribadi saya tidak punya masalah sama sekali!
ljs
Sudah ada jawaban yang bagus, jadi sebagai pelengkap saja, sepasang konten yang membahas FP dan Ruby: code.google.com/p/tokland/wiki/RubyFunctionalProgramming slideshare.net/tokland/functional-programming-with-ruby-9975242
tokland
1
Jika ada yang tertarik dengan topik ini, silakan tonton ini dan Anda akan belajar bagaimana ruby ​​dapat digunakan secara fungsional, apa akar dari pemrograman fungsional, mengapa ruby ​​bukan bahasa fungsional meskipun mampu memprogram secara fungsional: youtube .com / watch? v = 5ZjwEPupybw
maddin2code

Jawaban:

29

Saya sangat yakin Anda dapat menggunakan gaya fungsional di Ruby.

Salah satu aspek terpenting untuk dapat memprogram dalam gaya fungsional adalah jika bahasanya mendukung fungsi tingkat tinggi ... seperti yang dilakukan Ruby.

Meskipun demikian, mudah untuk memprogram Ruby dengan gaya non-fungsional juga. Aspek kunci lain dari gaya fungsional adalah tidak memiliki status, dan memiliki fungsi matematika nyata yang selalu mengembalikan nilai yang sama untuk sekumpulan masukan tertentu. Ini bisa dilakukan di Ruby, tetapi tidak diterapkan dalam bahasa seperti sesuatu yang lebih berfungsi ketat seperti Haskell.

Jadi, ya, ini mendukung gaya fungsional, tetapi juga akan memungkinkan Anda memprogram dalam gaya non-fungsional juga.

Mike Stone
sumber
4
Dengan menggunakan kriteria ini, apakah menurut Anda Smalltalk berfungsi karena memiliki blok?
OscarRyz
Jawaban bagus tapi satu nitpick - fungsi tingkat tinggi tidak sepenuhnya diperlukan untuk gaya fungsional. Misalnya, Anda dapat mencapai gaya fungsional di Java (yang tidak memiliki fungsi kelas satu / urutan lebih tinggi) dengan mendefinisikan objek fungsi dan menyusunnya untuk mendapatkan efek yang sama sebagai fungsi urutan yang lebih tinggi.
mikera
2
Hanya, ingin menyatakan bahwa @peter bertanya Is ruby a functional language?dan dengan jawaban langsung adalah tidak sederhana. Ruby adalah bahasa Berorientasi Objek dengan beberapa fitur fungsional.
Elias Perez
58

Apakah suatu bahasa adalah atau bukan bahasa fungsional tidaklah penting. Pemrograman Fungsional adalah tesis, paling baik dijelaskan oleh Philip Wadler (The Essence of Functional Programming) dan John Hughes (Why Functional Programming Matters).

Sebuah pertanyaan yang berarti adalah, 'Seberapa setuju Ruby mencapai tesis pemrograman fungsional?' Jawabannya 'sangat buruk'.

Saya memberikan ceramah tentang ini baru-baru ini. Ini slide-nya.

Tony Morris
sumber
3
Slide yang Anda berikan tidak menyebutkan mengapa Ruby "sangat tidak setuju untuk mencapai tesis FP." Mengapa C # lebih bisa diterima daripada Java (OK, fungsi anonim lebih mudah?)? Apakah karena Anda dapat memiliki variabel global di Ruby?
kizzx2
7
Tidak, slide tidak membahas detail ini, karena ini adalah topik yang cukup luas. Dengan risiko penyederhanaan yang berlebihan, misalnya, Ruby memberlakukan model evaluasi (call-by-value) yang memastikan non-komposisionalitas program. Implikasi dari hal ini dapat dengan mudah diremehkan. Ruby juga menikah dengan gagasan bahwa program adalah urutan efek. Artinya, Ruby berusaha keras untuk membuatnya sulit / tidak dapat diubah untuk menggunakan model komputasi lainnya. Saya harap komentar singkat ini membantu.
Tony Morris
2
1 untuk menunjukkan ambiguitas dalam mengklasifikasikan bahasa sebagai fungsional. Sial, saya telah menulis fungsional C!
Eli
1
Mengapa C # lebih bisa diterima daripada Ruby?
dan_l
1
Secara efektif merupakan jawaban hanya tautan karena mengalihdayakan bagian penting dari penjelasan (sebenarnya seluruh penjelasan) ke tautan eksternal. Sekarang tautannya mati, jawabannya menjadi tidak berguna.
ivan_pozdeev
34

Ruby memang mendukung fungsi level yang lebih tinggi (lihat Array # map, inject, & select), tetapi ini masih merupakan bahasa yang penting, Berorientasi Objek.

Salah satu karakteristik utama dari bahasa fungsional adalah bahwa ia menghindari keadaan yang bisa berubah. Bahasa fungsional tidak memiliki konsep variabel seperti yang Anda miliki di Ruby, C, Java, atau bahasa imperatif lainnya.

Karakteristik kunci lain dari bahasa fungsional adalah bahwa bahasa ini berfokus pada pendefinisian program dalam istilah "apa", bukan "bagaimana". Saat memprogram dalam bahasa OO, kita menulis kelas & metode untuk menyembunyikan implementasi ("bagaimana") dari "apa" (nama kelas / metode), tetapi pada akhirnya metode ini tetap ditulis menggunakan urutan pernyataan. Dalam bahasa fungsional, Anda tidak menentukan urutan eksekusi, bahkan pada level terendah.

Mike
sumber
3
Saya setuju dengan sebagian besar pernyataan Anda, namun, saya tidak setuju dengan "Bahasa Fungsional tidak memiliki konsep variabel seperti yang Anda miliki di Java, dll." Di haskell, Anda dapat menggunakan variabel dalam fungsi murni, Anda bahkan dapat menetapkan fungsi ke variabel, perbedaan terbesar adalah bahwa setelah variabel ditetapkan, variabel tidak dapat dimodifikasi setelahnya.
HHC
6
HHC, menurut definisi, variabel adalah nilai yang bisa berubah . Apa yang Anda bicarakan adalah nilai.
Scala Newb
Memang "variabel yang tidak dapat dimodifikasi" Haskell hanyalah fungsi konstan tanpa parameter (definisi).
raindev
16

Saya menyampaikan bahwa mendukung, atau memiliki kemampuan untuk memprogram dalam suatu bahasa dalam gaya fungsional bukanlah suatu bahasa fungsional.

Saya bahkan dapat menulis kode Java dalam gaya fungsional jika saya ingin menyakiti kolega saya, dan diri saya sendiri beberapa bulan kemudian.

Memiliki bahasa fungsional tidak hanya tentang apa yang dapat Anda lakukan, seperti fungsi tingkat tinggi, fungsi kelas satu, dan kari. Ini juga tentang apa yang tidak dapat Anda lakukan, seperti efek samping dalam fungsi murni.

Ini penting karena ini adalah bagian besar dari alasan mengapa program fungsional, atau kode fungsional dalam generel, lebih mudah untuk dipikirkan. Dan ketika kode lebih mudah untuk bernalar, bug menjadi lebih dangkal dan mengambang ke permukaan konseptual di mana mereka dapat diperbaiki, yang pada gilirannya memberikan lebih sedikit kode buggy.

Ruby berorientasi objek pada intinya, jadi meskipun Ruby memiliki dukungan yang cukup baik untuk gaya fungsional, itu sendiri bukanlah bahasa fungsional.

Itu pendapat non-ilmiah saya.

Edit: Dalam retrospeksi dan dengan pertimbangan untuk komentar bagus yang saya terima untuk jawaban ini sejauh ini, saya pikir perbandingan berorientasi objek versus fungsional adalah salah satu apel dan jeruk.

Pembeda sebenarnya adalah bersikap imparatif dalam eksekusi, atau tidak. Bahasa fungsional memiliki ekspresi sebagai konstruksi linguistik utamanya dan urutan eksekusi seringkali tidak terdefinisi atau didefinisikan sebagai malas. Eksekusi yang ketat dimungkinkan tetapi hanya digunakan saat diperlukan. Dalam bahasa imparatif, eksekusi yang ketat adalah defaultnya dan sementara eksekusi malas dimungkinkan, sering kali sulit dilakukan dan dapat memiliki hasil yang tidak dapat diprediksi dalam banyak kasus edge.

Nah, itu pendapat non-ilmiah saya.

Chris Vest
sumber
Saya pikir Anda dapat membuat kasus yang jauh lebih baik untuk menyebut Ruby fungsional daripada Java .... tidak, Ruby tidak sepenuhnya berfungsi, tetapi cukup mudah untuk menggunakan gaya fungsional di dalamnya ... dan seorang rekan gaya non-fungsional dapat dengan mudah mengubahnya kembali ke non-fungsional
Mike Stone
1
Ya, Mike, jika Anda ingin membuat kode dengan gaya fungsional, maka Ruby adalah peningkatan besar atas Java. Saya hanya menggunakan Java untuk membesar-besarkan dan menekankan inti permasalahannya.
Chris Vest
Jadi karena D memiliki fungsi murni, Anda akan menyebut D sebagai bahasa fungsional? digitalmars.com/d/2.0/function.html#pure-functions
Peter Burns
3
Banyak orang menganggap bahasa fungsional Lisp dan Skema, sebagian besar karena penggunaan fungsi anonim yang meluas. Namun, mereka kekurangan fungsi murni yang terjamin. Membatasi istilah untuk bahasa yang mendukung fungsi murni tampaknya terlalu membatasi.
skymt
13

Ruby harus memenuhi persyaratan berikut agar berfungsi "BENAR-BENAR".

Nilai yang tidak dapat diubah : setelah "variabel" ditetapkan, variabel tidak dapat diubah. Di Ruby, ini berarti Anda secara efektif harus memperlakukan variabel seperti konstanta. Tidak sepenuhnya didukung dalam bahasa ini, Anda harus membekukan setiap variabel secara manual.

Tidak ada efek samping: ketika melewati nilai tertentu, suatu fungsi harus selalu mengembalikan hasil yang sama. Ini sejalan dengan memiliki nilai-nilai yang kekal; sebuah fungsi tidak pernah dapat mengambil nilai dan mengubahnya, karena ini akan menyebabkan efek samping yang bersinggungan dengan mengembalikan hasil.

Fungsi tingkat tinggi: ini adalah fungsi yang memungkinkan fungsi sebagai argumen, atau menggunakan fungsi sebagai nilai yang dikembalikan. Ini, bisa dibilang, salah satu fitur paling penting dari bahasa fungsional apa pun.

Currying: diaktifkan oleh fungsi tingkat tinggi, kari mengubah fungsi yang mengambil banyak argumen menjadi fungsi yang mengambil satu argumen. Ini sejalan dengan aplikasi fungsi parsial, yang mengubah fungsi multi-argumen menjadi fungsi yang membutuhkan lebih sedikit argumen daripada aslinya.

Pengulangan: perulangan dengan memanggil fungsi dari dalam dirinya sendiri. Jika Anda tidak memiliki akses ke data yang dapat berubah, rekursi digunakan untuk membangun dan merangkai konstruksi data. Ini karena perulangan bukanlah konsep fungsional, karena membutuhkan variabel untuk diteruskan untuk menyimpan keadaan pengulangan pada waktu tertentu.

Evaluasi malas, atau evaluasi tertunda: menunda pemrosesan nilai sampai saat itu benar-benar dibutuhkan. Jika, sebagai contoh, Anda memiliki beberapa kode yang menghasilkan daftar angka Fibonacci dengan evaluasi malas diaktifkan, ini tidak akan benar-benar diproses dan dihitung hingga salah satu nilai dalam hasil diperlukan oleh fungsi lain, seperti put.

Proposal (Hanya pemikiran) Saya akan sangat senang jika memiliki beberapa jenis definisi untuk memiliki filemode arahan untuk mendeklarasikan file dengan paradigma fungsional, misalnya

mode 'fungsional'

Elias Perez
sumber
2
Sama sama. Saya ingin mengundang Anda untuk membaca tentang bahasa fungsional. Lisp menjadi kakek dari semua bahasa fungsional, ML (CAML) dan Erlang / Elixir. Itu benar-benar mengubah perspektif Anda tentang berbagai hal. Saya bukanlah seorang ahli, tetapi mahasiswa ilmu komputer yang terus-menerus menikmati membaca dan mempelajari hal-hal baru.
Elias Perez
Jawaban yang terorganisir dengan baik. Akan sangat menyukai beberapa eksplorasi tambahan tentang seberapa baik ruby ​​mendukung hal-hal ini. Saya percaya fungsi urutan yang lebih tinggi, kari dan rekursi semuanya didukung / mungkin di ruby, tolong koreksi saya jika saya salah.
Michael Dorst
9

Ruby adalah bahasa multi-paradigma yang mendukung gaya pemrograman fungsional.

skymt
sumber
4

Ruby adalah bahasa berorientasi objek, yang dapat mendukung paradigma lain (fungsional, imperatif, dll). Namun, karena semua yang ada di Ruby adalah sebuah objek, itu pada dasarnya adalah bahasa OO.

contoh:

"hello" .reverse () = "olleh", setiap string adalah instance objek string dan seterusnya dan seterusnya.

Baca di sini atau di sini

camflan.dll
sumber
Saya tidak pernah benar-benar mengerti bagaimana "segala sesuatu adalah objek" membuat Ruby lebih OO. Saya setuju bahwa Ruby pada dasarnya adalah OO, tetapi "everything is an object" hanya berarti bahwa tidak ada tipe "primitif", yang memiliki sedikit pengaruh pada kemampuan pengembang untuk menulis program dalam gaya OO, mengingat adanya primitif jenis umumnya hanya berarti ada empat atau lima jenis yang tidak memiliki metode apa pun.
Michael Dorst
4

Itu tergantung pada definisi Anda tentang "bahasa fungsional". Secara pribadi, saya pikir istilah itu sendiri cukup bermasalah bila digunakan sebagai absolut. Ada lebih banyak aspek untuk menjadi "bahasa fungsional" daripada sekadar fitur bahasa dan paling bergantung pada dari mana Anda mencari. Misalnya, budaya di sekitar bahasa cukup penting dalam hal ini. Apakah itu mendorong gaya fungsional? Bagaimana dengan perpustakaan yang tersedia? Apakah mereka mendorong Anda untuk menggunakannya secara fungsional?

Kebanyakan orang akan menyebut Skema sebagai bahasa fungsional, misalnya. Tapi bagaimana dengan Common Lisp? Terlepas dari masalah beberapa / ruang nama tunggal dan penghapusan tail-call yang dijamin (yang juga didukung oleh beberapa implementasi CL, tergantung pada pengaturan kompiler), tidak banyak yang membuat Scheme sebagai bahasa yang lebih cocok untuk pemrograman fungsional daripada Common Lisp, dan tetap saja, kebanyakan Lisper tidak akan menyebut CL sebagai bahasa fungsional. Mengapa? Karena budaya yang mengelilinginya sangat bergantung pada fitur-fitur penting CL (seperti makro LOOP, misalnya, yang mungkin tidak disukai oleh sebagian besar Schemers).

Di sisi lain, programmer C mungkin menganggap CL sebagai bahasa fungsional. Kebanyakan kode yang ditulis dalam dialek Lisp tentunya jauh lebih fungsional dalam gaya daripada blok kode C Anda yang biasa. Demikian juga, Skema adalah bahasa yang sangat penting dibandingkan dengan Haskell. Oleh karena itu, menurut saya tidak akan pernah ada jawaban pasti ya / tidak. Apakah akan memanggil suatu bahasa berfungsi atau tidak sangat bergantung pada sudut pandang Anda.

Matthias Benkard
sumber
Dalam hal apa Haskell bukan bahasa yang murni berfungsi? Atau bagaimana dengan Miranda (bahasa pemrograman fungsional yang kurang terkenal)? course.cs.washington.edu/courses/cse505/99au/functional/… "Haskell adalah bahasa fungsional murni standar,"
barlop
2

Ruby sebenarnya bukan bahasa multi-paradigma, menurut saya. Multi-paradigma cenderung digunakan oleh orang-orang yang ingin memberi label bahasa favorit mereka sebagai sesuatu yang berguna di berbagai bidang.

Saya akan menjelaskan Ruby adalah bahasa scripting berorientasi objek. Ya, fungsi adalah objek kelas satu (semacam), tetapi itu tidak membuatnya menjadi bahasa fungsional. IMO, saya bisa menambahkan.

JesperE
sumber
4
Jenis bahasa ditentukan oleh gaya pemrograman yang didukungnya; yang, pada gilirannya, ditentukan oleh fitur-fitur yang dimilikinya. Fungsi kelas satu dan anonim = pemrograman fungsional minimal. Ruby mendukung pemrograman OO tetapi tidak membutuhkannya: Anda tidak perlu mendefinisikan kelas. Karenanya, multi-paradigma.
skymt
2

Rekursi biasa terjadi dalam pemrograman fungsional. Hampir semua bahasa mendukung rekursi, tetapi algoritme rekursif seringkali tidak efektif jika tidak ada optimasi panggilan ekor (TCO).

Bahasa pemrograman fungsional mampu mengoptimalkan rekursi ekor dan dapat mengeksekusi kode tersebut dalam ruang yang konstan. Beberapa implementasi Ruby mengoptimalkan rekursi tail, yang lainnya tidak, tetapi secara umum implementasi Ruby tidak diharuskan untuk melakukan TCO. Lihat Apakah Ruby melakukan Pengoptimalan Panggilan Tail?

Jadi, jika Anda menulis beberapa gaya fungsional Ruby dan mengandalkan TCO dari beberapa implementasi tertentu, kode Anda mungkin sangat tidak efektif di interpreter Ruby lain. Saya pikir inilah mengapa Ruby bukan bahasa fungsional (begitu pula Python).

sastanin
sumber
TCO menarik, karena pada dasarnya mengubah perilaku program. Dalam kasus tertentu, ini tidak terlihat oleh program, tetapi dalam kasus lain, ini, misalnya, pengecualian backtraces. Oleh karena itu, ini tidak selalu merupakan pengoptimalan yang sesuai.
ioquatix
2

Sebenarnya, tidak masuk akal untuk mendeskripsikan bahasa sebagai "fungsional"; kebanyakan bahasa mampu untuk pemrograman fungsional. Bahkan C ++.

Gaya fungsional kurang lebih merupakan bagian dari fitur bahasa penting, didukung dengan gula sintaksis dan beberapa pengoptimalan penyusun seperti keabadian dan perataan rekursi ekor,

Yang terakhir ini bisa dibilang adalah teknis implementasi khusus kecil dan tidak ada hubungannya dengan bahasa yang sebenarnya. Kompiler x64 C # 4.0 melakukan optimasi tail-rekursi, sedangkan x86 tidak karena alasan bodoh apa pun.

Gula sintaksis biasanya dapat dikerjakan sampai batas tertentu atau yang lain, terutama jika bahasa tersebut memiliki precompiler yang dapat diprogram (yaitu C's #define).

Mungkin akan sedikit lebih bermakna untuk bertanya, "apakah bahasa __ mendukung pemrograman imperatif?", Dan jawabannya, misalnya dengan Lisp, adalah "tidak".

Rei Miyasaka
sumber
1

Silakan, lihat di awal buku: "A-Great-Ruby-eBook" . Ini membahas topik yang sangat spesifik yang Anda tanyakan. Anda dapat melakukan berbagai jenis pemrograman di Ruby. Jika Anda ingin memprogram secara fungsional, Anda dapat melakukannya. Jika Anda ingin membuat program seperti imperatif, Anda dapat melakukannya. Ini adalah pertanyaan definisi bagaimana Ruby berfungsi pada akhirnya. Silakan, lihat balasan oleh pengguna camflan.

Léo Léopold Hertz 준영
sumber