İşlevsel programlama sadece farklı mı, yoksa gerçekten daha mı zor?


12

İşlevsel programlama sadece farklı mı , yoksa gerçekten dahazor ?

Programlamayı daha önce hiç öğrenmemiş ve işlevsel programlama öğretilmiş birini söyleyin. daha önce hiç programlama öğrenmemiş ve zorunlu programlama öğretilmiş birine karşı. hangisini daha zor bulacak? ya da aynı?

Benim sorum: sorun şimdi bir giriş deve durumda olduğunu söylemek,

öyle qwe_asd_zxc_rty_fgh_vbnolurqweAsdZxcRtyFghVbn

Usul yolu:

  1. boyunca böl _
  2. ilk öğeyi atlayarak dizi içinde döngü
  3. her giriş için ilk harfi büyük yazıyoruz
  4. sonuçlara birlikte katıl

İşlevsel yol:

  1. _dönüş bulamazsainput
  2. cut inputilk boyunca _(biz almak öyle qweve asd_zxc_rty_gfh_cvb)
  3. ilk harfini büyük heado ve concatf(tail)

Tamam, işlevsel bir geçmişe sahipseniz ve prosedürel programlama konusunda önemli deneyime sahipseniz, şunu sormak istiyorum: prosedürel yolu bulmanız daha uzun sürecek mi yoksa fonksiyonel yolu bulmanız daha uzun sürecek mi?

Yordamsal bir geçmişiniz varsa, ancak işlevsel programlama konusunda uzun yıllara dayanan bir deneyime sahipseniz, aynı soruyu sormak istiyorum: yordamsal yolu anlamanız daha uzun sürecek mi yoksa işlevselliği anlamanız daha uzun sürecek mi? yolu?


5
Ehrm, eğer mapmutasyona uğratan bir döngü yerine 3. adım için kullanırsak, "prosedürel yol" benim için çok işlevsel görünüyor . İkinci yaklaşım, yalnızca standart kütüphanede bölünmüş fonksiyon yoksa dikkate alacağım bir şeydir (bu durumda, aynı zamanda kullanmayan zorunlu bir çözümle karşılaştırılmalıdır split).
sepp2k

8
Örneklerinizden herhangi birinde özel olarak işlevsel veya prosedürel hiçbir şey yoktur. İşlevsel programlamanın hatalı bir anlayışından tahmin etmeye çalıştığınız gibi geliyor. Olağandışı sonuçlar elde etmenize şaşmamalı.
Rein Henrichs

Fonksiyonel programlamanın zor olduğunu düşünmüyorum, sadece farklı. Programlama deneyiminiz yoksa öğrenmesi de kolaysa, ancak bir nedenden dolayı zorunlu programlamayı öğrendikten sonra, fonksiyonel programlama zorlaşır.
dan_waterworth

1
JavaScript, C #, Groovy gibi ana akım dilleri gittikçe daha fazla işlevsel özellik içerdiğinden, işlevsel ve prosedürel ayrımın tartışmalı hale geldiğini düşünüyorum.
user281377

2
Zorunlu programlama, daha önce programlama deneyimi olmayanlar için çok daha zor ve sezgiseldir. Gibi bir ifade x=x+1beklenmedik bir beyni havaya uçurabilir. Fonksiyonel programlama doğaldır, saf ve rahat kesinlikle matematiksel fonksiyonlardan başka bir şey değildir.
SK-logic

Yanıtlar:


12

Sadece farklı. Fonksiyonel programlama, çoğu insanın aşina olduğu matematik ile çok daha yakından ilgilidir. Tüm "değişmez değişkenler" olayı, zorunlu değişken programcılara sadece "değişebilir" zihniyetin derinden kök saldığı bir şok getirir.

Yeni gelenler için, sadece bir şeyin değerini değiştiremeyeceğiniz oldukça sezgiseldir .

CS okuduğum yerde ilk kursumuz olarak fonksiyonel bir dil öğretildi. Ve C ++ veya Java öğrenmiş olan herkes daha önce bununla mücadele etmişti. Programlamaya yeni başlayanlar bunu oldukça kolay bir şekilde aldı.


jalf programlamada yeni olanlardan birisin ve onu kolayca aldın mı?
Pacerier

Arada bir yerdeydim. O zamandan önce C ++ ve biraz PHP ile biraz dürttüm, ama gerçekten zorunluluk zihniyetine alışmak için yeterli değil. Sınıfa bir bütün olarak baktığınızda model oldukça açıktı. Ayrıca, bu neredeyse on yıl önceydi, bu yüzden hayır, bugün programlama konusunda yeni değilim;)
jalf

Değişken değişkenler? Mathematica işlevsel bir programlama dili değil mi? matematiksel değişkenler kesinlikle değiştirilebilir, değil mi?
user56834

20

Sadece farklı

Programladığınız zaman, temelde mantıksal yolunuzu koda çevirirseniz, düşüncelerinizle son çözüm arasındaki mesafenin "bilişsel boşluk" olduğu söylenebilir. Boşluk ne kadar büyük olursa köprü kurmanız o kadar zor olacaktır.

Prosedürel bir geçmişe sahipseniz, kendinizi prosedürel olarak düşünmek için eğitmiş olacaksınız, böylece boşluk fonksiyonel koddan daha az olacaktır ve bunun tersi de geçerlidir.

Bir programlama paradigmasının kendinden daha kolay olmasının tek yolu, sıradan bir dil gibi zaten bildiğiniz bir şeyle eşleşmesi olabilir, bu nedenle daha kısa bir boşlukla başlarsınız.

İşlevsel ve prosedürel olarak zaten oldukça akışkan bir kavramdır ve üst üste binme eğilimindedirler


4

Evet, fonksiyonel programlama birçok insanın kavraması zor olma eğilimindedir (özellikle yordamsal programlamaya daha önce maruz kalmış olanlar).

Ayrıca fonksiyonel programlama örneğinizin gerçekten fonksiyonel programlama için çok iyi bir örnek olmadığını söyleyebilirim. Özyineleme kullanıyor ve durumu değiştirmek yerine bir sonuç oluşturuyor, ancak bundan daha fazlasını değil.

İşlevsel programlamanın daha iyi bir örneğini elde etmek için daha genel bir sorunu göz önünde bulundurun: "bir alt çizgi arayın ve bir sonraki harfi büyük harfe dönüştürün" yerine, bunu bir model arama ve bulundu.

Pek çok dil bunu desteklemektedir, ancak bunu yapmak için kalıbı normal bir ifade gibi bir şey olarak belirtmemizi gerektirir. Bununla birlikte, düzenli ifadeler özel amaçlı bir programlama dilinden başka veya daha az bir şey değildir ve RE uygulaması bu dil için bir derleyici ve / veya yorumlayıcıdır. RE'nin derlenmesinin sonucu temel olarak ifadeyi bazı girdilerle eşleştirmek için (özel bir RE sanal makinesinde) yürüten bir işlevdir.

Perl gibi bir şeyde, deseni belirtmek için özel bir dil ve bu dizeyi işlev gibi bir şeye dönüştürmek için özel bir derleyici ve işlev benzeri şeyi yürütmek için özel bir yorumlayıcı kullanırsınız. İşlevsel bir dilde, genellikle deseni belirlemek için dilin kendisini kullanır ve gerçek bir işlev üretmek için dilin kendi derleyicisini kullanırsınız . Bu işlevi anında oluşturabiliriz (istediğimiz zaman RE'yi derleyebileceğimiz gibi), ancak bunu yaptığımızda sonuç, bunu yapmak için özel RE öğelerine ihtiyaç duymak yerine dildeki diğer herhangi bir işlev gibi çalışabilir.

Sonuç o zamanın olabilir nispeten kolayca yukarıdaki sorunu genelleme. Bununla birlikte, '_' ve "büyük harf" i doğrudan dönüştürmeye kodlamak yerine, şöyle bir şeye sahip olabiliriz:

s&r(pattern, transform, string) {
    if (!pattern(string))
        return string
    else
        return transform(matched part of string) + s&r(rest of string);
}

Ancak, kalıbı RE olarak belirlediğimiz bir şeyden farklı olarak, kalıbı doğrudan gerçek bir işlev olarak belirleyebilir ve yine de bunu kullanabiliriz:

my_pattern(string) return beginning(string) == '_';

Ve sonra bu işlevi s & r'ye geçiriyoruz. Şu anda oldukça önemsiz bir işlev ve bunu tamamen statik olarak kodladık. İşlevsel bir dil, RE'ler gibi kullandığımızda ve kullanıcı girişi gibi bir şeye dayalı olarak tamamen yeni bir işlev oluşturduğumuzda büyük ölçüde ilginç hale gelir, ancak RE'nin aksine, bu işlevin çalışması için özel bir RE yorumlayıcısına ihtiyaç duymaz - diğerleri gibi normal bir işlev.


4

Racket'in tam kodu :

;; camelize : string -> string
(define (camelize str)
  (let ([parts (regexp-split #rx"_" str)])
    ;; result of regexp-split is never empty
    (apply string-append
           (first parts)
           (map string-titlecase (rest parts)))))

(camelize "qwe_asd_zxc_rty_fgh_vbn")
;; => "qweAsdZxcRtyFghVbn"

Prosedürel deneyime sahip fonksiyonel bir programcı olarak, prosedürel bir çözümü "anlamanın" daha uzun süreceğini düşünmüyorum, ama kesinlikle yazmam daha uzun sürecek.

BTW, orijinal gönderide beklenen örnek sonuç yanlış: sonuna yakın bir "h" eksik.


gd bunu işaret ettiğin için. editör
Pacerier

3

Evcil hayvan teorim, programlama modellerinin gerçek bilgisayar çalışmalarına ne kadar yakın olduklarını anlamak daha kolay olduğudur. İşaretçilerin aslında makine adresleri olduğunu anlayana kadar anlamak zor. Küçük bir örneğe bilinçli olarak adım atana, yığın karelerini görene ve aynı değişkenin farklı değerlerinin saklandığı yerde fark edene kadar özyinelemeyi anlamak zordur. Bu, montajcı programlamanın yüksek seviyeli programlamadan daha kolay olduğu anlamına gelmez, ancak nasıl yapıldığını görmek, programlamada veya genel olarak kullanılabilirlikte, yeterliliğin anahtarı olan zihinsel model için harikalar yaratır.

Şimdi, prosedürel model olağan makine mimarisine biraz daha yakındır: ödevler bellek (veya kayıt) yazarlarıdır. Prosedür çağrıları sadece süslü sıçramalar, bir ifaslında bir koşullu atlamadır, ancak Lisp'te, örneğin, sözcüksel bir bağlamaya veya lambda ifadesine basit bir düşük seviyeli eşdeğeri yoktur. Bunu anlamak, dil seviyesi ile fiziksel makine arasında tamamen ayrı bir soyut fonksiyonel makine hayal etmenizi gerektirir, çünkü görünüşe göre çoğu insan bu kadar uzağa gitmez.

(Ben değilim von Neumann mimarisi sonuçta keyfi olduğu fikrine aşina ve bunun yerine doğrudan bu alakasız makine mimarisinin ayrıntıları ve birlikte önyargı acemi zihinleri programlama dillerinden semantik onları tanıtmak olmamalıdır. Aslında ettik Ama giderek daha asil ama yanlış yönlendirilmiş bir hedef olduğunu hissediyorum; insanlar aşağıdan yukarıya anlayış geliştirerek programlamayı öğreniyorlar ve fonksiyonel programlamanın yolu biraz daha uzun.)


7
Bu mantık ile Assembler tüm dilleri öğrenmenin en kolay yolu olmalı :)
Homde

4
Fonksiyonel programlamanın doğru yönden gelip gelmediğini anlamak oldukça kolaydır. Bahsettiğiniz "soyut fonksiyonel makine" basitçe cebirdir . Değerlendirme dönem yeniden yazma ile yapılır; fonksiyon uygulaması ikame ile yapılır. Programcılar problemleri yıllarca matematik derslerinde gördükleri araçları kullanarak çözmeyi öğrenirler. Eğer CS peşinde koşarlarsa, kaplumbağa yığınını daha sonra karşılamak için yeterli zaman vardır; değilse, hala yararlı problem çözme becerileri ve tasarım ilkeleri öğrendiler. Programları Nasıl Tasarlayacağınıza bir göz atın .
Ryan Culpepper

2
@mko Hayır, bu mantıkla gerçek bayt kodları 011011001001101...öğrenmesi en kolay dil olurdu!
MarkJ

2
@konrad: RISC toplayıcısı muhtemelen öğrenmesi en kolay dildir. Nasıl faydalı bir şey yapacağını bilmek hep birlikte başka bir hikaye ...
Bryan Boettcher
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.