Fonksiyonel programlama okunabilirliği [kapalı]


13

Bunu merak ediyorum çünkü herhangi bir fonksiyonel dili öğrenmeden önce hatırlıyorum, hepsini korkunç, korkunç, korkunç okunamaz buldum. Şimdi Haskell ve f # biliyorum, daha az kod okumak için biraz daha uzun sürüyor, ama bu küçük bir kod bir zorunlu dilde eşdeğer bir miktardan çok daha fazlasını yapar, bu yüzden net bir kazanç gibi hissediyor ve son derece değilim işlevsel olarak uygulanmaktadır.

İşte sorum, OOP milletinden sürekli olarak fonksiyonel tarzın korkunç derecede okunaksız olduğunu duyuyorum. Durumun bu olup olmadığını merak ediyorum ve kendimi kandırıyorum ya da fonksiyonel bir dil öğrenmek için zaman ayırırlarsa, tüm stil artık OOP'tan daha okunamaz olmaz mı?

Herhangi bir kanıt gördü ya da herhangi bir şekilde böyle söyleyecek kadar sık ​​sık gördükleri herhangi bir anekdot var mı? İşlevsel olarak yazmak gerçekten daha düşük okunabilirliğe sahipse, kullanmaya devam etmek istemiyorum, ancak durumun bu olup olmadığını gerçekten bilmiyorum ..


1
İşlevsel programlama hakkında neredeyse hiç bir şey bilmediğimde ve "Vay canına basmayı hatırladığımda" Süper Nario Kardeşler " koduna bakmayı hatırlıyorum. Bu gerçekten okunabilir görünüyor '
WuHoUnited



3
@BlackICE linq ve lambdas, "işlevsel programlama" tanımlamaktan çok uzaktır . İşlevsel programlama, yazım sistemlerini daha sık içermez, çünkü işlevleri yalnızca nesneler / sınıflar / kayıtlar türler olarak değil, tür olarak tanımaya başladığınızda, çok sayıda yeni yetenek ve teknikle sonuçlanırsınız. LINQ ve Lambda ifadeleri (veya liste monad ve yüksek dereceli fonksiyonlar) sadece iki spesifik sonuç tekniğidir ve bunlardan çok daha fazlası vardır.
Jimmy Hoffa

Yanıtlar:


15

Kod okunabilirliği çok özneldir . Bu nedenle, farklı insanlar aynı kodu okunabilir veya okunamaz olarak değerlendirir.

Bir ödev, x = x + 1bir matematikçiye garip geliyor, çünkü bir ödev yanıltıcı bir şekilde karşılaştırmaya benziyor.

Basit bir OOP tasarım modeli, bu kalıplara aşina olmayan biri için tamamen belirsiz olacaktır. Singleton'u düşünün . Birisi "Neden özel bir kurucuya ihtiyacım var? Gizemli yöntem getInstance() nedir? Neden küresel bir değişken oluşturup orada bir nesne atamıyoruz?"

Aynısı bir FP kodu için de geçerlidir. Sahne arkasındaki mantıksal kalıpları bilmediğiniz sürece , çok temel bir şeyi anlamak bile çok zor olacaktır, örneğin bir işlevi başka bir işleve argüman olarak nasıl geçireceğiniz.

Bunu söyledikten sonra, FP'nin gümüş bir kurşun olmadığını anlamak gerekir. FP'nin uygulanmasının zor olacağı birçok uygulama vardır ve bu nedenle daha kötü okunabilir bir koda yol açacaktır .


İnsanlar kendilerine benzeyen bir şey yaratmalılar (insanlık). Örneğin bilgisayar görüşünde bile artık sinir ağlarımız var. İnsan vücudu nesnelerden, niteliklerden, yöntemlerden oluşur ve nesneleri, nitelikleri, yöntemleri kullanarak diğer şeyleri açıklarız. Yani fonksiyonel programlama bir anlam ifade etmiyor
user25

12

Kısa cevap:

İnsanlara fonksiyonel programlama kodunun okunmasının zor olduğunu söyleyen unsurlardan biri, daha kompakt bir sözdizimini tercih etmesidir.

Uzun cevap:

Fonksiyonel programlamanın kendisi okunabilir veya okunamaz olamaz, çünkü bu bir kod yazma tarzı değil, bir paradigmadır. Örneğin C # 'da fonksiyonel programlama şöyle görünür:

return this.Data.Products
    .Where(c => c.IsEnabled)
    .GroupBy(c => c.Category)
    .Select(c => new PricesPerCategory(category: c.Key, minimum: c.Min(d => d.Price), maximum: c.Max(d => d.Price)));

ve Java, C # veya benzeri dillerde yeterli deneyime sahip herhangi bir kişi tarafından okunabilir kabul edilir.

Dil sözdizimi, popüler OOP dillerine kıyasla birçok işlevsel dil için (Haskell ve F # dahil) daha kompakttır ve sade İngilizce sözcük yerine sembollere tercih eder.

Bu, FP dışındaki diller için de geçerlidir. Popüler OOP dillerini, daha fazla İngilizce kelime kullanma eğiliminde olan daha az popüler olanlarla karşılaştırırsanız, sonuncusu programlama deneyimi olmayan kişiler için anlaşılması daha kolay olur.

Karşılaştırmak:

public void IsWithinRanges<T>(T number, param Range<T>[] ranges) where T : INumeric
{
    foreach (var range in ranges)
    {
        if (number >= range.Left && number <= range.Right)
        {
            return true;
        }
    }

    return false;
}

için:

public function void IsWithinRanges
    with parameters T number, param array of (Range of T) ranges
    using generic type T
    given that T implements INumeric
{
    for each (var range in ranges)
    {
        if (number is from range.Left to range.Right)
        {
            return true;
        }
    }

    return false;
}

Aynı şekilde:

var a = ((b - c) in 1..n) ? d : 0;

hayali bir dilde şöyle ifade edilebilir:

define variable a being equal to d if (b minus c) is between 1 and n or 0 otherwise;

Kısa sözdizimi ne zaman daha iyidir?

Yeni başlayanlar için daha ayrıntılı sözdizimini anlamak daha kolay olsa da, deneyimli geliştiriciler için daha kompakt sözdizimi daha kolaydır. Daha kısa kod yazmak daha az karakter anlamına gelir, bu da daha fazla üretkenlik anlamına gelir.

Özellikle, bir kişiyi sözdiziminden çıkarılabilecek bir şeyi belirtmek için bir anahtar kelime yazmaya zorlamak mantıklı değildir.

Örnekler:

  • PHP'de function, bunu yapmak için özel bir neden olmaksızın, her işlev veya yöntemden önce yazmanız gerekir .

  • Ada, özellikle otomatik tamamlama ile doğru IDE olmadığından, geliştiricileri birçok İngilizce kelime yazmaya zorladığı için beni her zaman dehşete düşürdü. Son zamanlarda Ada'yı kullanmadım ve resmi eğitimleri bitti, bu yüzden örnek veremem; herhangi birinin bir örneği varsa, cevabımı değiştirmekten çekinmeyin.

  • Sözdizimi 1..nbirçok FP (ve Matlab) 'de kullanılan, ile ikame edilmiş olabilir between 1, nya da between 1 and nya da between (1, n). betweenAnahtar kelime çok daha kolay dil sözdizimi aşina olmayan, ama yine de, iki nokta yazmak için çok daha hızlı insanlar için anlaşılması mümkün kılar.


8
Duyguya katılıyorum, ama farklı nedenlerle. O var olmayan bir uzman nasıl kolayca hakkında yazmak kod genellikle çok daha sık yazılır daha okunur okunmaz kodu. Daha kısa kod olabilir de yardım okunabilirliği, değerli zamanını, ekran alanı ve zihinsel kapasiteyi israf etmeyerek şey zaten daha kısa göstergesinden bariz olurdu (örneğin, yerine noktalı virgül ait yeni satırlar, iki tesadüf zaten). O olur zaman da zarar verebilir çok şifreli (örneğin tercihim for x in xsüzerinde for x xsbenim döngü değişkeni ve konteyner ayırt yardımcı olduğu için).

FP'den şikayet ettiğim çoğu insan, belirttiğiniz gibi listelediğiniz C # snippet'inden de şikayet ediyor, aynı zamanda FP'nin bir örneğidir. Çoğu OOP insanının bu snippet'i okunabilir bulması belki de meslektaşlarımın okunabilirliğinden daha fazla bir sorundur, ancak çoğu OOP insanının deneyimlerimden tamamen ikna olmadım ... bu yüzden neden bu konuda bu kadar emin olmadığımı hissediyorum.
Jimmy Hoffa

@Jimmy Hoffa: Bkz. Programcılar.stackexchange.com/a/ 158721/6605 Burada tam olarak C # snippet'ini ve yeni başlayan programcılar tarafından nasıl algılandığını tartışıyorum.
Arseni Mourzenko

1
@Sergiy: Java veya C # 'da bir yöntem imzasında methodanahtar kelime yoktur . Örnek: public int ComputePrice(Product product). PHP'nin yaptığı gibi böyle bir anahtar kelime eklemek, işleri daha kolay okumak yerine sadece karışıklık ekler. Bir programcı bir işlevin imzasından bir işlev olduğunu anlayamazsa, ya bu programcının hiçbir deneyimi yoktur ya da kod şimdiye kadar gördüğüm en kötü parça kodundan çok daha okunaksızdır.
Arseni Mourzenko

1
@Sergiy: ayrıntı düzeyinin yardımcı olabileceği durumlar var (aksi takdirde dilleri ve kodları görecektik p i ComputePrice(product): _.unitPrice * ~.cart[_]), ancak bazı diller onu çok ileri itiyor. functionPHP'deki gereksiz anahtar kelime örneği iyi bir örnektir.
Arseni Mourzenko

6

Bunun nedenlerinden birinin fonksiyonel programlamanın çok daha soyut kavramlarla çalışma eğiliminde olduğunu düşünüyorum. Bu, kavramları bilen ve anlayan insanlar için kodu daha kısa ve daha okunabilir hale getirir (çünkü sorunun özünü uygun bir şekilde ifade ettikleri için), ancak bunlara aşina olmayan insanlar için okunamaz.

Örneğin, işlevsel bir programcı için, Maybemonad veya Eithermonad içindeki farklı noktalarda başarısız olabilecek bir kod yazmak doğaldır . Veya, Statemonad'ın yardımıyla durumsal bir hesaplama yazmak için . Ancak monad kavramını anlamayan biri için, bunların hepsi bir çeşit siyah büyücülük gibi görünüyor.

Bu yüzden, bir OOP çalışanlarından oluşan bir ekipte bile, işlevsel programlama parçalarını kullanmanın, bir işlevi veya kapanışları olan bir koleksiyon üzerinde eşleme gibi anlaşılması veya öğrenilmesi kolay kavramlar kullanması mantıklı olacağını düşünüyorum .

(Ve tabii ki, bir parça kod yazan programcıya da bağlıdır. Herhangi bir dilde korkunç bir şekilde okunamayan kod yazabilir, ayrıca güzel ve temiz bir tarzda yazabilirsiniz.)


2

Okunabilirliğin paradigmalar, modeller ve benzerleri ile ilgisi yoktur. Kod, sorunlu alanınızın anlambilimini ne kadar çok yansıtırsa, bu tür bir sorunlu alanın terminolojisi ve deyimleri ne kadar çok çalışırsa, o kadar okunabilir.

OOP kodunun hiç okunabilir olmamasının nedeni budur: birçok gerçek dünya probleminin doğal olarak hiyerarşik taksonomiler açısından ifade edilmemesi. Mesajları birbirine geçen nesneler tuhaf bir kavramdır ve "gerçek" olan her şeyden çok uzaktır. Şaşırtıcı bir şekilde, fonksiyonel deyimlere doğal olarak eşleştirilebilen çok daha gerçek dünya kavramları var. Sorunlar deklaratif olarak tanımlanma eğilimindedir, bu nedenle deklaratif bir çözüm daha doğaldır.

Bununla birlikte, gerçek dünyaya saf işlevsel, saf OOP, saf veri akışı veya saf olan her şeyden daha yakın olabilecek birçok anlambilim vardır. Ve bu nedenle, problem çözme için dil odaklı bir yaklaşım, mevcut tüm "saf" paradigmaları yenerek en okunabilir kodu üretir. Etki alanına özgü dillerle her sorun kendi doğal terminolojisinde ifade edilir. Ve fonksiyonel diller, DSL'lerin uygulanmasını kolaylaştırmada OOP ana akımlarından biraz daha iyidir (ancak daha iyi yaklaşımlar mevcuttur).


1

Kod okunabilirliği özneldir. Eminim bazı insanlar bunu anlama eksikliği nedeniyle eleştirir. Ortak örüntülerin uygulanma biçiminde doğal olarak farklı deyimler vardır. Örneğin, Ziyaretçi kalıbı, kalıp eşleşmesi olan bir dilde gerçekten anlamlı değildir .

Tür çıkarımı zor bir özellik olabilir. Genellikle, bu büyük bir gelişme hızlandırıcıdır, ancak kafa karıştırıcı hatalara yol açan bağlam eksikliği nedeniyle hangi türlerin dahil olduğunu anlamak bazen zor olabilir. Bu Fonksiyonel Programlama dilleri ile sınırlı değildir - C ++ şablonlarında da gördüm!

Modern diller çoklu paradigma olma eğilimindedir . Buna hem C # hem de F # dahildir. C # 'da fonksiyonel bir stil ve F #' da zorunlu bir stil yazmak mümkündür. İşlevsel dilleri eleştiren aynı kişiler muhtemelen nesne yönelimli dillerinde işlevsel kod yazarlar.

İşlevsel dillerde ticari gelişme hâlâ nispeten olgunlaşmamaktadır. Herhangi bir dilde kötü form olarak kabul edilecek bir takım hatalar gördüm. Gibi:

  1. Dili öğrenirken (ve yeniden düzenleme yapmadan) tarzı değiştirmek tutarsızlığa yol açar.
  2. Bir dosyada çok fazla.
  3. Bir satırda çok fazla ifade var.

Hatalarla ilgili olarak şunu da ekleyeceğim: 4. Sembollerin aşırı kullanımı, örneğin: ~ @ # $% ^ & * () -_ + = \ | /.,; 5. Örtük özellikler: isteğe bağlı bildirimler / anahtar kelimeler / ifadeler, örtük dönüşümler, vb .;
Sergiy Sokolenko
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.