Fonksiyonel programlama kodda karmaşıklık ekler mi? [kapalı]


17

Geçtiğimiz yıl boyunca (Java geçmişinden gelen) Scala kodu yazıldım . Vals, vaka sınıfları, harita / filtre / lambda fonksiyonları, çıkarımlar ve tür çıkarımı ile nasıl daha basit ve daha temiz bir kod oluşturabileceğinizi gerçekten sevdim. Daha çok Akka tabanlı bir uygulama için kullandım.

Bu yıl, fonksiyonel programlamayı gerçekten seven yeni bir ekiple Scala projesinde çalışıyorum. Scalaz'ı yoğun bir şekilde kullanıyorlar ve kod her yerde uygulamalar, bağlam sınırları, okuyucu / yazar / eyalet monad ile dolduruluyor, hatta ana yöntem bir I / O monadına "sarılıyor". Onların mantığı, bu kodun doğru olduğunu ve her fonksiyonun yan etkiler içermediğini iddia ederek derleyicinin "bizim için çalışmasını" sağlamasıdır.

Yine de, benim bakış açımdan, tüm bu sözdizimi gerçekten iş mantığının önüne geçer. Örneğin, bir tür "MyBusinessObject" iyidir ve "List [MyBusinessObject]", "Option [MyBusinessObject]" veya "Future [MyBusinessObject]" gibi türler de iyidir. Hepsinin açık bir anlamı ve amacı var. Öte yandan, aşağıdaki gibi kodlayın:

def method[M[_]: Applicative] = {
  case (a, b) => (ca[M](a) |@| cb[M](b)) {
    case t @ (ra, rb) =>
      if (ra.result && rb.result) t.right
      else t.left
  }
}

programa karmaşıklık katıyor mu, yoksa ben bu programlamaya alışkın değil miyim?


6
Objektif olarak cevaplanabilir sorunuz nedir?
Deer Hunter

1
Görünüşe göre bir veya iki harfli değişken adlarıyla bir ton koda yol açar. Biraz APL gibi görünüyor. Bu bir tamamlayıcı değil.
user949300

3
Geçen yıl Haskell ile oynamaya başladım. O gibi kısa, sembolik işlevler, bir yeri vardır ki ben .. Haskell Scalaz benzer vs-işlemden, funktorlar, monads, gibi kavramları anlamadığı zaman, zaman inanılmaz derecede karmaşık görünüyordu >>=ve <$>ortalama hangi bir şey sizin kadar ne yaptıklarını bilmek. Ne demek istediklerini öğrendikten sonra, şimdi bana çok doğal ve hızlı bir şekilde okuyorlar. Gerçekten bir cevap değil, sadece böyle şeylerle objektif deneyimim. Scala'yı da kullanıyorum, ancak Scalaz kütüphanesi ile ilgili hiçbir deneyimim yok.
KChaloux

3
Deyimlere aşina değilsiniz. @ user949300 kısa değişkenleri fonksiyonel kodların birçoğu için gerçekten bir problem değildir (Matematik tarzı kurallarını düşünün!). Ayrıca anlam, tür veya ayrıntılı değişken isimlerini neyin daha iyi ilettiğine dair daha ayrıntılı bir tartışma için Tony Morris'in blogunu okuyun.
Andres

3
@ user949300: kısa değişken adları yerel olarak tercih edilir, bu işlevsel ve zorunlu dünyalarda aynıdır ( for(i=0; i<7; ++i) { trivialOperation(i); }bazı garip trivialOperationCountdeğişkenlerle yazmazsınız, değil mi?) Şimdi, desen eşleşmesi ile fonksiyonel programlama dilleri bazen size daha fazla değişken getirecektir. O sadece erişimci yöntemi çağrıları OO yazmak. Sonuç genellikle daha özlüdür; belki biraz daha az açıklayıcıdır, ancak veri beyanına bakmak normalde bunu çabucak netleştirir. Statik yazım çok yardımcı olur, APL'deki gibi değildir.
leftaroundabout

Yanıtlar:


37

Bunun işlevsel programlama ile hiçbir ilgisi yoktur - bu tür bir durumu başka herhangi bir programlama dili bağlamında bulabilirsiniz - okunabilirlik ve işleri basit tutmayla ilgili herhangi bir ortak duyguyu göz ardı edecek kadar "kendi" dilinin gelişmiş yapılarını seven geliştiriciler. C, C ++, Perl, Java, C #, Basic ve işlevsel olmayan diğer dillerde böyle bir durumla karşılaştım. Programcıların kodlara karmaşıklık katan fonksiyonel programlama değil.

Beni yanlış anlamayın, gelişmiş dil özelliklerinden kaçınmanızı önermiyorum - ancak verilen bağlamda doğru dengeyi bulmak önemlidir. Tüm dünyada 100.000'den fazla geliştiricinin kullanımı için genel bir kütüphane yazarken, yalnızca yerel ofisiniz için ayrı bir rapor oluşturucu yazarken uygulanacak farklı önlemler vardır.


7
Ayrıca toplulukla çok ilgisi var. Java veya C # arka planına sahip bir geliştirici için kod zorlukla anlaşılabilir (ve topluluğu da bunu anlayamaz). Ancak, örneğin Haskell yazarsanız ve monad, aplikatör, functor vb. Kullanmıyorsanız, o dilin topluluğunu şaşırtırsınız. Kodun “doğallığı” doğal değil, topluma ve yerleşik uygulamalara göre.
Andres

1
Bunu görmek zor çünkü çoğumuz zorunlu arka planlardan geliyoruz, bu da bazen doğal olanla ilgili yanlış varsayımlar yapmamıza neden oluyor.
Andres

sadece amatör için çok daha okunabilir olarak yazılabilir SLT C ++ kütüphanesine bakın
cırcır ucube

@ratchetfreak: Sanırım STL demek istiyorsun. Bence bu çok iyi bir örnek (ve aslında cevabımda bunu aklımda bulundurdum). STL programcısı olduğunuzda şablon meta programlamayı kullanmak çok mantıklıdır, çünkü STL'yi yeniden kullanılabilir hale getirir. Ve bu kodu korumak zorunda olan insanlar normalde meta programlamayı şablonlamak için de kullanılır. Standart iş uygulamanızda şablon meta programlamanın STL benzeri bir şekilde kullanılması, kolayca aşırı karmaşık, bakımı zor kodlara yol açabilir. İş uygulamalarında bile TMP'nin iyi olduğu (nadir) vakaları elbette bulabilirsiniz.
Doc Brown

@DocBrown evet disleksi yanlış zamanda başladı, ama dürüst olmak gerekirse (ve şimdi sahip olduğumdan çok daha fazla zaman) yarı bir zihnim varsa, çok daha okunabilir olması için birçok işlev gövdesini yeniden yazabilirdim.
cırcır ucube

7

Kodlama şekline en azından resmin bir parçası olduğuna alışmadığınızı söyleyebilirim. Seninle benzer bir durumdayım (C # 'dan F #' a geliyorum ve Haskell geçmişi olan insanlarla çalışıyorum) ve ilginç bir deneyim bulduğumda, kafamı duvara vurduğumda, özellikle kıvrılmış noktasız fonksiyon bileşimi, orada olanları asmak için. Bu kültürel bir şey.

Bu özel kod programa karmaşıklık ekleyip eklemediğine gelince - bilmiyorum. Genel bir kod parçasının karmaşık olabileceğini kabul etti. Ama bu bir iş programı, iş mantığının bir parçası değil. Kod tabanını daha karmaşık veya basit hale getirip getirmediğini bilmek istiyorsanız, bu kod parçası olmadan nasıl görünmesi gerektiğini düşünmeniz gerekir. Bu tür jenerik yapılarda genellikle karmaşık oldukları görülür, ancak tek bir ekrana sığabileceğiniz bir karmaşıklıktır. Aynı zamanda tüm kod tabanını biraz daha basit hale getirir. Bu özellikle monadlarda geçerlidir.

Sonra tekrar, @Doc Brown'un önerdiği gibi, 'sanat uğruna sanat' örneği de olabilir. Bunu da göz ardı edemezsiniz.


5

Ben genel fonksiyonel programlamada iddia ediyorum azaltır ve böylece kanununun nasıl çalıştığını anlamak için çalışırken dikkate alınması gereken durumlarda sayısını azaltarak, değişken durumunu ortadan kaldırarak karmaşıklığı.

Bununla birlikte, fonksiyonel programlama daha yüksek soyutlama derecelerini mümkün kılar ve son derece soyut bir kod son derece yararlı olsa da, anlaşılması zor olabilir, çünkü tanım gereği, anlayışınızı yönlendirmek için normalde kullanacağınız bağlamdan ayrılmıştır. İş nesneleriyle ilgili "Hepsinin açık bir anlamı ve amacı var" yorumunuz şüphesiz doğrudur, ancak bu mantığın zaten anladığınız bir ihtiyaç ve bağlama çok özel olduğu gerçeğinin bir yansımasıdır. Monad gibi bir yapının varlığı, çok az çaba ile çok yararlı bir şey yapmanıza izin verir, ancak web, bir Monad'ın ne olduğunu açıklamaya çalışan sayfalarla doludur. Bu sizin için bir soyutlama.

Ayrıca Scalaz, FP'yi uzun süredir yiyip soluyan insanlar tarafından yazıldı; Haskell'deki işlevselliği Scala'ya getirmek istediler. Bunu yaparken pedagojik olma girişiminde bulunmadılar. Scalaz, yazarlara açık ve anlaşılır görünen ama deneyimsiz olanlara yabancı görünen bir kelime ve stil kullanır. Geri kalanlarımıza kafa karıştırıcı yöntemler, Haskell geçmişleri göz önüne alındığında, yazarlar için o kadar açık görünüyordu ki, bir yorum bile garanti etmediler.

Ayrıca, işlevsel bir programlama dili olarak Scala, Scalaz yazarlarını bazı durumlarda daha çirkin kod yazmaya zorlayan bazı eksikliklere sahiptir (kısmen JVM'nin eksiklikleri vardır). Örneğin, genel kuyruk çağrısının ortadan kaldırılması, bazı kodlarda trambolin kullanımını zorlar ve "tür bir sistem" in olmaması tip imzaları zorlaştırabilir.

Ve son olarak, Scalaz kendini çok iyi kullanıyor. Bu, gücünün bir işareti olarak düşünülebilir, ancak başlatılmamışlar için kaynağı bir bulmaca yapabilir - baktığınız herhangi bir rastgele kod parçası, size yabancı görünen başka bir şeyden yararlanır.

Pes etme. Ve bu yardımcı olabilir.


-4

Programa karmaşıklık katıyor mu, yoksa sadece bu şekilde programlamaya alışkın değil misiniz?

Sizce bu olasılıklar aynı şey değil mi?

İyi yazılmış kod, belirli programlama diline aşina olmayan kişiler tarafından okunabilir. Bazı diller (BASIC, Pascal, vb.) Daha önce hiç programlama dili görmemiş okul çocukları tarafından okunabilir ve anlaşılabilir.

Diğer dillerle ve Scala ile deneyime sahip olan (ve en azından bir hafta boyunca Scalaz ile çalışmış ve daha karmaşık şeyleri açıklamak için meslektaşları olan) birisinin hala kafası karışmışsa; o zaman karmaşıklığı arttırdığının kanıtı budur.


11
Bu doğru değildir:"Well written code can be read by people who aren't familiar with the specific programming language."
Andres F.

@Andres: Bu doğrudur ... bir noktaya. İyi yazılmış kod, iş mantığını uygulama ayrıntılarından ayıracaktır ve iş mantığı okunabilir olmalıdır, çünkü yaptığı şeyin çoğu, iyi adlandırılmış yardımcı işlevlere doğrudan çağrı yapmaktır. Bu yardımcılar elbette her türlü dil özelliğini kullanabilir ve anlamak için dil ve kütüphanelerle ilgili ağır deneyim gerektirebilir.
Ben Voigt

4
Ben şu deyimsel APL olduğuna inanıyorum: x[⍋x←6?40]. Sizce ne işe yarıyor? Kesinlikle bilemezdim…
bdesham

3
@Brendan Sadece aynı paradigma içinde (ve o zaman bile bazen değil). Örneğin, Prolog, Java ve APL o kadar farklıdır ki, bunlardan sadece birini (ve başka bir dili bilmiyorsanız), ilkini ne kadar iyi biliyor olursanız olun diğer ikisini okuyamazsınız. (Cidden, bdesham örneğinde, herhangi bir APL bilmiyorsanız, şeytan nasıl "yılbaşı ağacı" yorumlamak gerekiyor?)
Izkata

1
Brendan, iyi yazılmış tanımınız standart değil. İyi yazılmış her zaman dile ve topluluğuna göredir. X dilinde bir program, buggy değilse, iyi yazılmış ve verimli ve açık ... verilen kitle için! Bu, genel olarak yazılı dil için geçerlidir: her zaman kitlenizi tanıyın. Bilimsel bir makale için uygun olan (muhtemelen), muhtemelen annenize bir e-posta için uygun değildir.
Andres
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.