İşlevsel bir dil öğrenmek daha iyi bir OOP programcısı yapar mı? [kapalı]


28

Bir Java / C # / C ++ programcısı olarak fonksiyonel diller hakkında çok fazla konuşma duydum, ancak bir tane öğrenmek için hiçbir zaman bir ihtiyaç duymadım. Ayrıca, işlevsel dillerde sunulan daha üst düzey düşünme seviyesinin sizi daha iyi bir OOP / prosedürel dil programcısı yaptığını duydum.

Bunu onaylayan var mı? Programlama becerilerinizi hangi yollarla geliştirir?

Daha az karmaşık bir dilde becerilerini geliştirmek amacıyla öğrenmek için iyi bir dil seçimi nedir?


3
Eğer C # kodluyorsan, zaten bir tane biliyorsun. LINQ oldukça işlevsel bir şey.
SK-mantık

Bence OOP gerçek hayattaki nesneleri modellemek için daha iyi.
Tulains Córdova

1
@ user61852 Çoğu OO tasarım deseni, "gerçek hayat" nesneleriyle ilgili hiçbir şey modellemez, ama aslında oldukça soyut kavramlardır.
Andres F.

Bir Java / C # (+ C ++) programcısından daha fazlası olun. 40'tan bıçak X'i neden seçtiğinizi belirten çok küçük olmayan bir kitapçık ile devasa bir İsviçre çakısı bıçağı arasında bir fark var. Kesinti gücünü çok çeşitli koşullara fazla düşünmeden uygulayabilmeniz için. (elbette sapında bir şişe
açacağıyla

Yanıtlar:


32

Ben temelde FrustratedWithFormsDesign en yanıta katılabilir , ancak yeni bir paradigma öğrenme kişinin becerilerini geliştirmeye yardımcı olur nasıl da istedi. Kendi tecrübelerime göre birkaç örnek verebilirim.

İşlevsel programlama öğrendiğimden beri, çalıştığım hangi kavramların daha doğal olarak “nesneler” olarak kabul edildiğinin (genellikle mutasyonun anlamlı olduğu yerlerde) ve daha doğal olarak değişmez “değerler” olarak değerlendirildiğinin farkındayım (önemli bir ayrım var. OO'nun anlamlı olduğu yere veya FP'nin anlamlı olduğu zamanlara dokunmak, ancak bu sadece benim görüşüm).

Kodumun nerede yan etkileri olduğunu fark ettim ve bu yerleri izole etmek için daha dikkatli oluyorum, bu da fonksiyonlarımdan daha "saf" işlevler yapıyor. Bu, OO kodumun test edilebilirliğini büyük ölçüde artırıyor.

Veri sunumumdaki çevrimler hakkında daha bilinçliyim. (Örneğin, Haskell'de bir bağlantılı listeyi iki kat bağlantılı bir listeye dönüştürmek için bir işlev yazabileceğinizi sanmıyorum, bu nedenle bu dilde biraz daha fazla döngü olduğunu farkedersiniz.) Döngüleri engellemek senkronizasyon miktarını azaltır veri yapılarının dahili olarak tutarlı olması için bu yapıları iş parçacığı arasında paylaşma yükünü hafifletmek için yapmanız gerekir.

Özyinelemeye güvenme ihtimalim daha yüksek (planın özyinelemeli döngü yapıları güzellik şeylerdir). Dijkstra , Yapısal Programlamaya İlişkin Notlar - özyinelemeli algoritmalar ile doğrudan entelektüel döngülerimizin doğru olduğunu kanıtlamanın tek yolu olduğunu öne sürdüğü matematiksel indüksiyonla eşleştirdiği için bunun önemine değindi . (Kodumuzu doğru kanıtlamamız gerektiğini önermiyorum, ancak kendimiz için daha kolay hale getirmemiz, kodumuzun doğru olması olasılığını artırıyor.)

Daha üst düzey işlevleri kullanma ihtimalim daha yüksek John Hughes'un makalesi, İşlevsel Programlamanın Neden Önemli ? Fonksiyonel programlama tekniklerini kullanarak elde edeceğiniz uyuşmazlığı vurgulamaktadır, üst düzey fonksiyonları büyük bir rol oynar.

Ayrıca, Jetti'nin cevabına değinildiği gibi , birçok OO fikrinin daha yeni OO dillerine dahil edildiğini göreceksiniz. Ruby ve Python'un her ikisi de birçok üst düzey işlev sunar, LINQ'nun monadik anlamalara destek sağlama çabası olarak tanımlandığını duydum, hatta C ++ 'ın şimdi lambda ifadeleri var.


@Aidan: wrt lambdas C ++ 0x, herhangi bir oranda yeni C ++ derleyicileri onları zaten dahil etti.
Matthieu M.

1
"Nesne" olarak "değişebilir durumu tutan şey" çok yaygındır, ancak Değer Nesnesi deseni uzun yıllardır kullanılmaktadır.
Frank Shearar,

@Matthieu, teşekkürler, metni yansıtacak şekilde güncelledim.
Aidan Cully

@ Frank: işaretçi için teşekkürler. Bunu cevaba dahil etmedim, ancak Değerleri Nesnelere yapmak zorunda olduğum ana itiraz, nesneler arasındaki ilişkilerin daha fazla olduğu nesneler / nesneler arasındaki farklılıklar / nesneler arasındaki farklılıklar ile ilgilidir. nesnelerin kendisinden daha birincil). 1 + 2matematiksel olarak eşdeğerdir 2 + 1, ancak 1.+(2)ondan farklı şekilde uygulanır 2.+(1). İşlemleri kullanarak nesne arayüzlerini kullanmaktan daha doğal olarak anlaşılabilecek bir takım SW problemleri vardır.
Aidan Cully,

1
@Aidan William Cook'un "Veri Soyutlamasını Anlama Üzerine, Tekrar Ziyaret Etme" konusunu okudunuz mu? Nesneler ve ADT'ler arasındaki farkları ortaya koyuyor, bu da ima ettiğiniz şeydir.
Frank Shearar

32

Sizi daha iyi bir OOP programcısı yapmanın garantili olduğunu söyleyemem, ama sizi yeni bir düşünce biçimiyle tanıştırır ve bu sizi genel olarak problem çözmede sadece OOP açısından daha iyi hale getirebilir .


3
Nesnelerin aslında daha üst düzey işlevler olduğu göz önüne alındığında, FP öğelerinin öğrenilmesinin doğrudan OOP'uma yardımcı olduğunu buldum. Dediğiniz gibi, daha genel olarak uygulanabilir / faydalı olsa da.
Frank Shearar,

12

İşlevsel bir dil öğrenmek - Benim için Lisp - paralel uygulamalar oluştururken gerçekten yardımcı olur. İşlevsel yöntemler (duruma göre, hiçbir yan etkisi yoktur) senkronizasyonu çok daha kolaydır ve sadece girdilerine bağlı olduklarından iplik güvenliğini sağlamak daha kolaydır. Bu, belirli bir kod alanı için izlemeniz gereken tek veri, girdiğiniz parametrelerdir. Bu da hata ayıklamayı kolaylaştırır.


Bunların ayrıca, görevleri olarak saf işlevler bekleme eğiliminde olan kitaplık kütüphanelerine de yardımcı olacağını göreceksiniz. Ayrıca dolaylı olarak da yardımcı olabilir, OO kodunu bir tür "işlevsel stilde" yazacağım yerler var, burada referans aldığı ve işlev tarafından kullanılan bir grup nesneye örtülü bir kilidi olan bir "sahip olma parametresi" var. . Beklentilerinizi belgelemeniz (ve üniteleri test etmeniz), bu size birkaç kilitleme sorunu ile daha iyi okuyuculu kod verebilir. Ve birkaç açık kilit.

Prolog'un işlevsel bir dil olarak adlandırıldığını hiç duymamıştım. Yeterince kısarsam, Prolog'un (kısımlarının) FP ile nasıl yardımcı olabileceğini belli belirsiz görebiliyorum.
Frank Shearar,

1
Prolog işlevsel bir dil değil. Mantıksal bir dil. Eğer bir Prolog- istiyorsanız gibi en yanı fonksiyonel programlama entegre olduğu mantık dil, zihin, sen bir kaz yakalayabilir Mercury . Uyarı: Prolog'u zaten bilseniz bile beyninizi biraz incitir.
SADECE MY DOĞRUDAN FAALİYET

@Sadece MY doğru görüş: Evet, bence haklısın. Sanırım fonksiyonel diller hakkında daha fazla şey öğrenmem gerekiyor!
Michael K,

1
@ moz: Evet, keşke Java'nın kuzuları olsaydı. İsimsiz Threadnesneler sakardır.
Michael K,

9

Öğrenme herhangi programlama diğer paradigmayı genel olarak programlama becerilerini geliştirecektir. Programlama, akademik araştırma sınıfı şeyler olmadığında (ve o zaman bile sık sık) programlama, temel olarak problem çözmedir. Bir kelimeyle, düşünerek. Çeşitli paradigmalar, problemler ve çözümleri hakkında farklı düşünme yöntemleridir. Bu yüzden sadece "işlevsel bir dil öğrenmek" olarak düşünmeyin. Bunu "sorunlar ve çözümleri hakkında düşünmenin farklı bir yolunu öğrenme" olarak düşünün. O zaman, hiç kullanmasanız bile bir dil öğrenmenin faydalarını göreceksiniz.

Özel sorunuza cevap vermek için, eskiden bir C ++ programcısıydım (C ++ için bir standart olmadan önce). Her zamanki gibi şeyleri, yöntemlerle, vb. İle manipüle edilmiş durumları tutan nesnelerle takip ettim. (Hiç kimsenin Haskell'i gerçekten öğrendiğini sanmıyorum.) O zamanlar alıştırmalar, grubuma atanan testçi meslektaşlarımdan birinin, kodumun test edilmesinin kolaylaştığı konusunda bir yorum yapmadıkça biraz boşa gitti.

Olan, nesnelerimi daha değişken hale getirmeye başladığımdı. Karmaşık değişken durumlu sınıflar, kendilerini yeni nesnelere döndürerek değişikliklerle klonlanan sınıfların yerini almaya başladı. Paylaşılan nesneler, üzerine yazma üzerine semantiği olan nesnelerle değiştirilmeye başlandı (böylece, bellek yükü olmadan çok sayıda nesne klonu yanılsaması veriyor). İşlevler, kesinlikle gerekli olmadıkça, hiçbir yan etkiye sahip değildi; "fonksiyon" un saf, matematiksel tanımı norm oldu. Bütün bunlar kodumda doğal olarak gerçekleşmeye başladı - işlevsel programlama alanını daha fazla araştırdığım için bilinçli bir düşünceye yer yoktu.

Şimdi her iki yılda bir en az bir yeni programlama paradigması (AOP gibi küçük bir uzatma paradigması olsa bile) ve her paradigma içinde en az iki yeni dil (mümkün olduğu kadar saf, bir tane daha hibrit / pratik) öğrenmeyi bir hedef haline getirdim ). Her biri bana, herhangi bir dilde programlamamın tümüne uygulanacak yeni entelektüel araçlar verdi, bu yüzden onları öğrenmek için harcanan zaman, bence biraz bile boşa gitmedi.


3

Daha önce de söyledim ve tekrar söyleyeceğim, fonksiyonel dilleri öğrenmek kesinlikle C # 'yı geliştirdi. Lambdaları anlamama yardım etti (ve onları sevmeme yardım etti). Ayrıca Asenkron işlemlerle çalışırken işlevsel programlamayı (F #) ne kadar çok tercih ettiğimin farkına varmamı sağladı!


3

Makine kodu, doğrudan işlemci tarafından doğrudan yürütülen komutların yan etki listesinden başka bir şey değildir. C'deki yan etkiler farklıdır, bunun yerine kayıtları ve fiziksel donanımı kullanmak yerine, bir dizi soyutlama yaparsınız ve derleyicinin tüm kirli işleri yapmasına izin verirsiniz. C ayrıca yan etkilerinizi döngüler halinde ve sonra ifadeler halinde yapılandırmanıza izin verir. C ++, dilde OOP ve gerekli bazı özellikleri ekleyerek C'yi geliştirir. Java ve C #, çöp toplama ekler ve Python dinamik yazım ekler.

Tüm bu özelliklerle bile - bu dillerdeki dinamik yazma, çöp toplama vb. Programlar hala tamamen yan etkilere dayanmaktadır. Scheme, Clojure, Haskell ve ML gibi fonksiyonel programlama dilleri tamamen farklı bir şeydir, bu diller matematikten sonra makine koduna daha yakındır. Aksine, yan etkileri kullanarak, fonksiyonların etrafında değerleri iletirsiniz.

Daha az karmaşık bir dilde becerilerini geliştirmek amacıyla öğrenmek için iyi bir dil seçimi nedir?

Düzeni öneririm , minimaldir ve MIT'nin eski tanıtım programlama sınıflarında kullanılmıştır. Diğer fonksiyonel programlama dillerini öğrenmek çok daha zordur. Clojure, Java'nın bütün karmaşıklıklarını beraberinde getiriyor, ML karmaşık bir statik tip sistemi de beraberinde getiriyor, Haskell bazen akademik bir dil olarak adlandırılıyor - yeni başlayanlar için ideal değil. Diğer yandan, şema öğrenmek ve anlamak kolaydır.

Programlama becerilerinizi hangi yollarla geliştirir?

Neredeyse tüm yüksek seviye programlama dilleri fonksiyonlara ve özyinelemeye sahiptir - fonksiyonel programlamanın dayandığı kavramlar. Bu nedenle, FP bilgilerinizin hemen hemen her yerde yararlı olması gerektiği için, ancak gerçekten işlevsel olarak programlamak istiyorsanız, doğal ve etkili bir dili kullanmak yerine, başka birisinin dil tasarımını beğeninize göre bükmeye çalışmalısınız. işlevsel programlama yapmak için işlevsel bir programlama dili kullanmalısı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.