Ruby işlevsel bir dil midir?


88

Wikipedia, Ruby'nin işlevsel bir dil olduğunu söylüyor, ancak ben ikna olmadım. Neden ya da neden olmasın?


4
Muhtemelen sorunuz çok kısa olduğu için, kişisel olarak hiçbir sorunum yok!
ljs

Zaten iyi cevaplar var, bu yüzden sadece onları tamamlamak için FP ve Ruby'yi tartışan bir çift içerik: code.google.com/p/tokland/wiki/RubyFunctionalProgramming slideshare.net/tokland/functional-programming-with-ruby-9975242
tokland

1
Bu konuyla ilgilenen varsa lütfen bunu izleyin ve Ruby'nin işlevsel bir şekilde nasıl kullanılabileceğini, işlevsel programlamanın köklerinin ne olduğunu, işlevsel programlama yeteneğine sahip olsa bile Ruby'nin neden işlevsel bir dil olmadığını öğreneceksiniz: youtube .com / watch? v = 5ZjwEPupybw
maddin2code

Yanıtlar:


29

Ruby'de işlevsel stili kesinlikle kullanabileceğinizi düşünüyorum.

İşlevsel bir tarzda programlayabilmenin en kritik yönlerinden biri, dilin daha yüksek dereceli işlevleri desteklemesidir ... Ruby bunu yapar.

Bununla birlikte, Ruby'de işlevsel olmayan bir tarzda programlamak da kolaydır. İşlevsel stilin diğer bir önemli yönü, duruma sahip olmamak ve belirli bir girdi kümesi için her zaman aynı değeri döndüren gerçek matematiksel işlevlere sahip olmaktır. Bu Ruby'de yapılabilir, ancak Haskell gibi daha katı bir şekilde işlevsel olan bir dilde uygulanmaz.

Yani, evet, işlevsel stili destekler, ancak aynı zamanda işlevsel olmayan bir tarzda programlamanıza da izin verir.


4
Bu kriteri kullanarak, Smalltalk'ın blokları olduğu için işlevsel olduğunu söyleyebilir misiniz?
OscarRyz

İyi yanıt ama bir nitpick - daha yüksek dereceli işlevler , işlevsel bir stil için kesinlikle gerekli değildir . Örneğin, Java'da (birinci sınıf / üst düzey işlevlere sahip olmayan) işlev nesnelerini tanımlayarak ve daha yüksek dereceli bir işlevle aynı etkiyi elde etmek için bunları oluşturarak işlevsel stil elde edebilirsiniz.
mikera

2
Sadece, @peter'ın sorduğunu Is ruby a functional language?ve doğrudan cevapla basit bir hayır olduğunu belirtmek isterim . Ruby, bazı işlevsel özelliklere sahip Nesne Yönelimli bir dildir.
Elias Perez

58

Bir dilin işlevsel bir dil olup olmadığı önemsizdir. Fonksiyonel Programlama, en iyi Philip Wadler (Fonksiyonel Programlamanın Özü) ve John Hughes (Neden Fonksiyonel Programlama Önemlidir) tarafından açıklanan bir tezdir.

Anlamlı bir soru şudur: 'Ruby, işlevsel programlama tezini gerçekleştirmeye ne kadar uygundur?' Cevap "çok kötü".

Yakın zamanda bununla ilgili bir konuşma yaptım. İşte slaytlar.


3
Verdiğiniz slaytlar Ruby'nin neden "FP tezini başarmak için çok zayıf bir şekilde yatkın" olduğundan bahsetmiyordu . C # neden Java'dan daha uygundur (Tamam, daha kolay anonim işlevler?)? Ruby'de global değişkenlere sahip olabileceğiniz için mi?
kizzx2

7
Hayır, slaytlar bu ayrıntıya girmiyor, çünkü bu oldukça kapsamlı bir konu. Örneğin, aşırı basitleştirme riski altında Ruby, programların bileşimsizliğini sağlayan bir değerlendirme modeli (değere göre çağrı) uygular. Bunun sonuçları kolayca tahmin edilebilir. Ruby ayrıca bir programın bir dizi efekt olduğu fikriyle de evlidir. Başka bir deyişle, Ruby başka herhangi bir hesaplama modelini kullanmayı zor / inatçı hale getirmek için kendi yolundan çıkar. Umarım bu kısa yorum yardımcı olur.
Tony Morris

2
Dilleri işlevsel olarak sınıflandırmadaki belirsizliğe işaret eden +1. Cehennem, işlevsel C yazdım!
Eli

1
C # neden Ruby'den daha uygundur?
dan_l

1
Açıklamanın kritik bölümünü (aslında açıklamanın tamamı) dış bir bağlantıya aktararak yalnızca bağlantı içeren bir yanıttır. Artık bağlantı öldüğüne göre, cevap işe yaramaz hale geldi.
ivan_pozdeev

34

Ruby, üst düzey işlevleri destekler (bkz. Dizi # eşleme, enjekte etme ve seçme), ancak yine de zorunlu, Nesne Yönelimli bir dildir.

İşlevsel bir dilin temel özelliklerinden biri, değişken durumdan kaçınmasıdır. İşlevsel diller, Ruby, C, Java ya da başka herhangi bir zorunlu dilde sahip olduğunuz gibi bir değişken kavramına sahip değildir.

İşlevsel bir dilin diğer bir temel özelliği, bir programı "nasıl" yerine "ne" açısından tanımlamaya odaklanmasıdır. Bir OO dilinde programlama yaparken, uygulamayı ("nasıl") "ne" den (sınıf / yöntem adı) gizlemek için sınıflar ve yöntemler yazıyoruz, ancak sonunda bu yöntemler bir dizi deyim kullanılarak yazılır. İşlevsel bir dilde, en düşük seviyede bile bir yürütme sırası belirtmezsiniz.


3
İfadenizin çoğuna katılıyorum, ancak, "İşlevsel Diller Java'da olduğu gibi değişken kavramına sahip değildir." Haskell'de, değişkenleri saf fonksiyonlarda kullanabilirsiniz, hatta bir değişkene bir fonksiyon bile atayabilirsiniz, en büyük fark, bir değişken atandığında daha sonra değiştirilememesidir.
HHC

6
HHC, tanımı gereği değişken, değişebilen bir değerdir . Bahsettiğiniz şey değerlerdir.
Scala Newb

Aslında Haskell'in "değiştirilemez değişkenleri" sadece parametreleri (tanımları) olmayan sabit fonksiyonlardır.
raindev

16

İşlevsel bir tarzda bir dilde programlamayı desteklediğini veya bu yeteneğe sahip olduğunu beyan ederim. işlevsel bir dil yapmadığını ileri sürüyorum.

İş arkadaşlarıma ve kendime birkaç ay zarar vermek istersem Java kodunu işlevsel bir tarzda bile yazabilirim .

İşlevsel bir dil olması sadece ilgili değil olabilir Üst düzey fonksiyonları, birinci sınıf işlevleri ve-işlemden olarak yapın. Aynı zamanda ne yapamayacağınla ilgili saf işlevlerdeki yan etkiler gibi .

Bu önemlidir, çünkü işlevsel programların ya da genel olarak işlevsel kodun neden daha kolay anlaşılabileceğinin büyük bir kısmıdır. Ve kodun akıl yürütmesi daha kolay olduğunda, hatalar daha sığ hale gelir ve sabitlenebilecekleri kavramsal yüzeye yüzer, bu da daha az hatalı kod verir.

Ruby, özünde nesne odaklıdır, bu nedenle işlevsel bir stil için oldukça iyi bir desteğe sahip olsa da, kendisi işlevsel bir dil değildir.

Bu benim bilimsel olmayan görüşüm zaten.

Düzenleme: Geriye dönüp baktığımda ve şu ana kadar bu yanıta aldığım güzel yorumları dikkate alarak, nesneye yönelik ve işlevsel karşılaştırmanın elma ve portakallardan biri olduğunu düşünüyorum.

Gerçek farklılaştırıcı, uygulamada etkisiz olmak ya da olmamaktır. Fonksiyonel diller, birincil dilsel yapıları olarak ifadeye sahiptir ve yürütme sırası genellikle tanımsızdır veya tembel olarak tanımlanır. Sıkı yürütme mümkündür, ancak yalnızca gerektiğinde kullanılır. Belirsiz bir dilde, katı yürütme varsayılandır ve tembel yürütme mümkün olsa da, çoğu zaman yapmak zordur ve birçok uç durumda öngörülemeyen sonuçlar verebilir.

Şimdi, bu benim bilimsel olmayan görüşüm.


Ruby'yi işlevsel olarak çağırmak için Java'dan çok daha iyi bir durum yaratabileceğinizi düşünüyorum .... hayır, Ruby tam olarak işlevsel değildir, ancak içinde işlevsel bir stil kullanmak oldukça kolaydır ... ve işlevsel olmayan bir stil meslektaşı bunu yapabilir kolayca işlevsiz duruma geri
Mike Stone

1
Evet Mike, işlevsel bir tarzda kodlamak istiyorsanız, Ruby Java'ya göre çok büyük bir gelişmedir. Java'yı sadece abartmak ve ana noktayı vurgulamak için kullanıyordum.
Chris Vest

Yani D'nin saf işlevleri olduğu için D'ye işlevsel bir dil mi diyorsunuz? digitalmars.com/d/2.0/function.html#pure-functions
Peter Burns

3
Pek çok kişi, büyük ölçüde anonim işlevlerin yaygın kullanımı nedeniyle Lisp ve Scheme işlevsel dillerini düşünür. Yine de, garantili saf işlevlerden yoksundurlar. Terimin, saf işlevleri destekleyen dillerle sınırlandırılması çok kısıtlayıcı görünmektedir.
skymt

13

Ruby'nin "GERÇEKTEN" işlevsel olması için aşağıdaki gereksinimleri karşılaması gerekir.

Değişmez değerler: Bir "değişken" ayarlandıktan sonra değiştirilemez. Ruby'de bu, değişkenlere sabitler gibi etkili bir şekilde davranmanız gerektiği anlamına gelir. Dilde tam olarak desteklenmiyor, her değişkeni manuel olarak dondurmanız gerekecek.

Yan efektleri olmayan: belirli bir değer iletildiğinde, bir işlev her zaman aynı sonucu döndürmelidir. Bu, değişmez değerlere sahip olmakla el ele gider; Bir fonksiyon asla bir değeri alıp değiştiremez, çünkü bu bir sonucu döndürmek için teğet olan bir yan etkiye neden olur.

Daha yüksek sıralı işlevler: Bunlar, işlevlere bağımsız değişken olarak izin veren veya döndürme değeri olarak işlevleri kullanan işlevlerdir. Bu, tartışmasız, herhangi bir işlevsel dilin en kritik özelliklerinden biridir.

Currying: Üst düzey işlevler tarafından etkinleştirilen currying , birden çok argümanı alan bir işlevi tek argüman alan bir işleve dönüştürmektir. Bu, çok argümanlı bir işlevi, başlangıçta yaptığından daha az argüman alan bir işleve dönüştüren kısmi işlev uygulamasıyla el ele gider.

Özyineleme: kendi içinden bir işlevi çağırarak döngü yapmak. Değişken verilere erişiminiz olmadığında, veri oluşturma ve zincirleme veri oluşturma için özyineleme kullanılır. Bunun nedeni, belirli bir zamanda döngünün durumunu depolamak için değişkenlerin geçirilmesini gerektirdiğinden döngü işlevsel bir kavram değildir.

Tembel değerlendirme veya gecikmeli değerlendirme: değerlerin işlenmesini gerçekten gerekli olan ana kadar ertelemek. Örnek olarak, tembel değerlendirme etkinleştirilmiş Fibonacci sayılarının listesini oluşturan bir kodunuz varsa, bu, sonuçtaki değerlerden biri koyma gibi başka bir işlev tarafından gerekene kadar işlenmez ve hesaplanmaz.

Öneri (Sadece bir düşünce) Bir tür tanıma sahip olmak harika olur.mode Dosyaları işlevsel paradigma ile bildirmek yönergeye , örnek

mod 'işlevsel'


2
Rica ederim. Sizi işlevsel diller hakkında okumaya davet ediyorum. Lisp, tüm işlevsel dillerin, ML (CAML) ve Erlang / Elixir'in büyük ebeveynidir. Gerçekten şeylere bakış açınızı değiştiriyor. Uzman değilim ama sürekli bir bilgisayar bilimi öğrencisi okumaktan ve yeni şeyler öğrenmekten zevk alır.
Elias Perez

İyi organize edilmiş cevap. Ruby'nin bunları ne kadar iyi desteklediğine dair bazı ek keşifler yapmak isterdim. Ruby'de üst düzey işlevlerin, currying'in ve özyinelemenin tümünün desteklendiğine / mümkün olduğuna inanıyorum, lütfen yanlışsam düzeltin.
Michael Dorst

9

Ruby, işlevsel bir programlama stilini destekleyen çok paradigmalı bir dildir.


4

Ruby, diğer paradigmaları (işlevsel, zorunlu, vb.) Destekleyebilen nesne yönelimli bir dildir. Bununla birlikte, Ruby'deki her şey bir nesne olduğu için, öncelikle bir OO dilidir.

misal:

"merhaba" .reverse () = "olleh", her dize bir dize nesnesi örneğidir vb.

Buradan veya buradan okuyun


"Her şey bir nesnedir" nin nasıl Ruby'yi daha OO yaptığını gerçekten anlamamıştım. Ruby'nin öncelikle OO olduğuna katılıyorum, ancak "her şey bir nesnedir" gerçekten sadece "ilkel" türlerin olmadığı anlamına gelir, bu da geliştiricinin OO tarzında programlar yazma becerisine çok az etkisi vardır, ilkel türler genellikle yalnızca herhangi bir yöntemi olmayan dört veya beş tür olduğu anlamına gelir.
Michael Dorst

4

"İşlevsel dil" tanımınıza bağlıdır. Şahsen, mutlak olarak kullanıldığında terimin kendisinin oldukça sorunlu olduğunu düşünüyorum. "İşlevsel bir dil" olmanın yalnızca dil özelliklerinden daha fazla yönü vardır ve çoğu nereden baktığınıza bağlıdır. Örneğin dili çevreleyen kültür bu bakımdan oldukça önemlidir. İşlevsel bir stili teşvik ediyor mu? Mevcut kütüphaneler ne olacak? Bunları işlevsel bir şekilde kullanmaya teşvik ediyorlar mı?

Örneğin, çoğu insan Scheme'yi işlevsel bir dil olarak adlandırır. Peki ya Common Lisp? Çoklu / tekli ad alanı sorunu ve garantili kuyruk çağrısı ortadan kaldırmanın dışında (derleyici ayarlarına bağlı olarak bazı CL uygulamaları da destekler), Scheme'yi bir dil olarak Common'dan daha uygun hale getiren pek bir şey yoktur. Lisp ve yine de, Lispers çoğu CL'yi işlevsel bir dil olarak adlandırmaz. Neden? Çünkü onu çevreleyen kültür, büyük ölçüde CL'nin zorunlu özelliklerine bağlıdır (örneğin, çoğu Schemer'in kaşlarını çatacağı LOOP makrosu gibi).

Öte yandan, bir C programcısı CL'yi işlevsel bir dil olarak görebilir. Herhangi bir Lisp lehçesinde yazılan kodların çoğu, her zamanki C kod bloğunuzdan kesinlikle çok daha işlevseldir. Aynı şekilde Scheme, Haskell ile karşılaştırıldığında çok zorunlu bir dildir. Bu nedenle, kesin bir evet / hayır cevabı olabileceğini sanmıyorum. Bir dili işlevsel olarak adlandırıp çağırmamak, büyük ölçüde bakış açınıza bağlıdır.


Haskell hangi yönden tamamen işlevsel bir dil değildir? Ya da Miranda'ya (daha az bilinen bir işlevsel programlama dili) ne dersiniz? course.cs.washington.edu/courses/cse505/99au/functional/… "Haskell, standart bir saf işlevsel dildir,"
barlop

2

Ruby de aslında çok paradigmalı bir dil değil bence. Çoklu paradigma, en sevdikleri dili birçok farklı alanda yararlı olan bir şey olarak etiketlemek isteyen insanlar tarafından kullanılma eğilimindedir.

Ruby'nin nesne yönelimli bir betik dili olduğunu tanımlardım. Evet, işlevler birinci sınıf nesnelerdir (bir nevi), ancak bu onu işlevsel bir dil yapmaz. IMO, ekleyebilirim.


4
Dil türü, desteklediği programlama stilleri ile tanımlanır; buna karşılık sahip olduğu özelliklere göre karar verilir. Birinci sınıf ve anonim işlevler = minimum işlevsel programlama. Ruby OO programlamayı destekler ancak bunu gerektirmez: asla bir sınıf tanımlamanıza gerek yoktur. Bu nedenle, çoklu paradigma.
skymt

2

Özyineleme, işlevsel programlamada yaygındır. Neredeyse her dil özyinelemeyi destekler, ancak yinelemeli algoritmalar, kuyruk arama optimizasyonu (TCO) yoksa genellikle etkisizdir .

Fonksiyonel programlama dilleri, kuyruk özyinelemesini optimize edebilir ve bu tür kodu sabit alanda çalıştırabilir. Bazı Ruby uygulamaları kuyruk özyinelemesini optimize eder, diğerleri yapmaz, ancak genel olarak Ruby uygulamalarının TCO yapması gerekmez. Bkz mu Yakut Kuyruk Çağrı Optimizasyonu gerçekleştirin?

Bu nedenle, Ruby işlevsel stili yazarsanız ve belirli bir uygulamanın TCO'suna güvenirseniz, kodunuz başka bir Ruby yorumlayıcısında çok etkisiz olabilir. Sanırım bu yüzden Ruby işlevsel bir dil değil (Python da değil).


TCO ilgi çekicidir çünkü esasen programın davranışını değiştirir. Bazı durumlarda, bu program tarafından görülemez, ancak diğer durumlarda, örneğin istisna geri izleri olur. Bu nedenle, her zaman uygun bir optimizasyon değildir.
ioquatix

2

Açıkçası, bir dili "işlevsel" olarak tanımlamak mantıklı değildir; çoğu dil işlevsel programlama yeteneğine sahiptir. C ++ bile.

İşlevsel stil, sözdizimsel şeker ve değişmezlik ve kuyruk yineleme düzleştirme gibi bazı derleyici optimizasyonları ile desteklenen, zorunlu dil özelliklerinin aşağı yukarı bir alt kümesidir.

İkincisi, muhtemelen uygulamaya özgü küçük bir tekniktir ve gerçek dille hiçbir ilgisi yoktur. X64 C # 4.0 derleyicisi kuyruk özyineleme optimizasyonu yapar, oysa x86 derleyici aptalca bir nedenle yapmaz.

Sözdizimsel şeker, özellikle dilin programlanabilir bir ön derleyicisine (yani C'nin # tanımına) sahip olması durumunda, genellikle bir dereceye kadar üzerinde çalışılabilir.

"Dil __ zorunlu programlamayı destekliyor mu?" Diye sormak biraz daha anlamlı olabilir ve örneğin Lisp ile cevap "hayır" dır.


1

Lütfen kitabın başına bir göz atın: "Harika-Yakut-e-Kitap" . Sorduğunuz çok özel konuyu tartışıyor. Ruby'de farklı programlama türleri yapabilirsiniz. İşlevsel olarak programlamak istiyorsanız, bunu yapabilirsiniz. Zorunlu olarak programlamak istiyorsanız, bunu yapabilirsiniz. Ruby'nin sonunda ne kadar işlevsel olduğu bir tanım sorusudur. Lütfen camflan kullanıcısının yanıtına bakınız.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.