Javascript İşlevsel Bir Programlama Dili mi


34
  • Javascript işlevsel bir dil midir? Nesneleri olduğunu biliyorum ve onunla birlikte OOP de yapabilirsin, ama aynı zamanda işlevsel bir dil mi, bu şekilde kullanılabilir mi?
  • OOP'un programlamadaki bir sonraki evrime nasıl dönüştüğünü / nasıl göründüğünü biliyorsunuz, bu, 'İşlevsel Programlamanın' bir sonraki evrim olduğu anlamına gelir (Not: Bu, görüşün bir sorusu DEĞİLDİR, ANCAK; moderatörler için katılımcılardan daha fazla;)).
  • Örnekler aracılığıyla en iyisini öğreniyorum, belki birileri aynı görevi OOP yönteminde ve sonra da İşlevsel Programlama biçiminde yerine getirerek işlevsel programlamanın ne yaptığını / karşılaştırdığını gösterebilir.

Dürüst olmak gerekirse 'İşlevsel Programlamayı' gerçekten anlamıyorum: P Javascript'i işlevsel programlama ile karşılaştırmak tamamen yanlış olabilir.

Fonksiyonel programlamayı laymans terimleriyle koymak: basitçe anonim fonksiyonlar kullanarak BÜYÜKTÜRÜNÜ soyutlamanın yararı mı?

Yoksa bu yol çok mu basit? Basit bir şekilde, OOP, nesnelerden soyutlamanın yararıdır, ancak OOP'yi tanımlamak için çok basit olduğuna inanıyorum.

Bu, işlevsel bir programlamanın iyi bir örneği midir?

Javascript OOP Örneği:

// sum some numbers
function Number( v )
{ 
  this.val = v;
}

Number.prototype.add( /*Number*/ n2 )
{
    this.val += n2.val;
}

İşlevsel programlama örneği:

function forEach(array, action) 
{
   for (var i = 0; i < array.length; i++)
       action(array[i]);
}  

function add(array)
{
    var i=0;
    forEach(array, function(n)
    {
        i += n;
    });
    return i;
}

var res = add([1,9]);

"İşlevsel programlama dili" nin tanımına bağlıdır. Geniş anlamda, kapalı değerleri olan, yani bir "lambda" yapısına sahip (lambda-calculus anlamında) işlevsel değerler oluşturma kabiliyeti olarak anlaşılabilir ve daha sonra Javascript tasarıya uyar.
Basile Starynkevitch

2
Or is that way too simple?Yeap, öyle. Anonim işlevler, bazen işlevsel dilleri ve işlevsel programlamayı destekleyen çoklu paradigma dilleriyle ilişkilidir, ancak işlev dillerinin benzersiz bir özelliği değildir. Fakat eğer onları cal-hesabının bir uygulaması olarak görüyorsanız, bunlar fonksiyonel programlamanın temel bir parçası, asıl nokta o kadar basit değil :)
yannis

Javascript tasarımı, uygulamaların kuyruk çağrısı optimizasyonu yapmasını önler. Kitaplarımda yalnız başına, işlevsel olarak etiketlenmesini önlüyor.
dan_waterworth

I know it has objects & you can do OOP with it alsoHayır yapamazsın. Sınıf ve nesne arasındaki ayrımı ortadan kaldıran prototip tabanlı programlama. Şahsen prototip tabanlı programlamanın bu temel seviyede hatalı olduğunu düşünüyorum.
RokL

Javascript işlevsel bir dil değil, işlevsel özelliklere sahip olduğundan emin değil, eski C zorunlulukları da var, aslında her dilin temel işlevsel özellikleri var. Haskell, ML, vb. Gibi saf bir işlevsel dil zorunlu, zorunlu olmayan bir dildir.
ALXGTV 11

Yanıtlar:


72

Javascript işlevsel bir dil midir? Nesneleri olduğunu biliyorum ve onunla birlikte OOP de yapabilirsin, ama aynı zamanda işlevsel bir dil mi, bu şekilde kullanılabilir mi?

Bazen insanlar, ne demek istedikleri zorunlu programlama veya prosedürel programlama olduğunda, fonksiyonel programlama diyebilir . Kesinlikle konuşursak, işlevsel programlama :

Bilgisayar bilimlerinde fonksiyonel programlama, hesaplamayı matematiksel işlevlerin değerlendirilmesi olarak ele alan ve durum ve değişken verileri önleyen bir programlama paradigmasıdır . Durum değişikliklerini vurgulayan zorunlu programlama tarzının aksine, fonksiyonların uygulanmasını vurgulamaktadır. Fonksiyonel programlama, 1930'larda fonksiyon tanımını, fonksiyon uygulamasını ve özyinelemeyi araştırmak için geliştirilen resmi bir sistem olan lambda hesabında köklerine sahiptir. Birçok fonksiyonel programlama dili, lambda hesabındaki detaylar olarak görülebilir.

Javascript yaygın olarak bilinmese veya işlevsel bir dil olarak kullanılmasa da, bazı işlevsel unsurları vardır :

JavaScript’in Scheme ile ortak bir yönü vardır. Dinamik bir dildir. S-ifadelerini kolayca simüle edebilen esnek bir veri tipine (diziler) sahiptir. Ve en önemlisi, işlevler kuzudır.

Program Lisp'in bir lehçesidir ve muhtemelen çoğu programcının işlevsel programlamayı tartışırken düşündüğü dillerden biridir. Nesne yönelimi söz konusu olduğunda , Javascript nesne yönelimli bir dildir. Ancak nesne yönelimi prototip tabanlıdır :

Prototip tabanlı programlama, sınıfların bulunmadığı nesne yönelimli bir programlama tarzıdır ve prototip görevi gören mevcut nesneleri klonlama işlemi yoluyla davranış yeniden kullanımı (sınıf tabanlı dillerde miras olarak bilinir) gerçekleştirilir. Bu model aynı zamanda sınıfsız, prototip odaklı veya örnek tabanlı programlama olarak da bilinir. Yetkilendirme, prototip tabanlı programlamayı destekleyen dil özelliğidir.

Her ne kadar Javascript nesne yönelimli olsa da, C ++, C #, Java ve PHP (ve epeyce diğerleri) dilleri gibi daha yaygın sınıf tabanlı modeli izlemiyor . Ve tabii ki, aynı zamanda zorunlu bir dildir; bu, yukarıda tarif ettiğim işlevsel programlama ile karışıklığa neden olur.

OOP'nin programlamadaki bir sonraki evrime nasıl dönüştüğünü / göründüğünü biliyorsunuz, bu, 'İşlevsel Programlamanın' bir sonraki evrim olduğu anlamına geliyor mu?

Nesne yönelimi ve fonksiyonel programlama birçok farklı programlama paradigmasından sadece ikisidir, farklı kavram ve soyutlamalara sahip farklı programlama stilleridir. Anahtar kelime "farklı" dır. Diğerlerinden daha iyi veya diğerlerinden daha iyi gelişen tek bir paradigma yoktur, her biri diğerlerinden daha iyi olan bazı senaryolara uyar. Bazıları orijinale göre diğerlerinden daha büyük olabilir, ancak daha uzun sürdüğü gibi onları daha iyi yapan evrimsel terimlerle. Ama bu ona bakmanın akıllıca bir yolu değil.

Javascript, yukarıda tanımladığım gibi ve diğer birkaç dilde olduğu gibi, çok paradigmadır. Zorunlu, prototip tabanlı nesne yönelimli ve fonksiyonel tarzda kod yazmanıza olanak sağlar. Hangi binaya en uygun hangisinin yapılacağını seçmek size kalmış. Birkaç tek paradigma dili de vardır; kanonik örnek yalnızca sınıf tabanlı nesne yönelimli programlama 1 için izin veren Java'dır .

Dilleri ve paradigmaları modaya uygun ifadeler olarak görme dürtüsüne gerçekten karşı koymalısınız. Orada, çoğunlukla fanboys / fangirls veya pazarlama yapan kişiler tarafından yazılmış, programlama (az) bilgisi ve programlama anlayışı ile yazılmış bir saçmalık var. "Daha iyi", "daha gelişmiş" vb. Gibi terimler geçerli değildir.

Örnekler aracılığıyla en iyisini öğreniyorum, belki birileri aynı görevi OOP yönteminde ve sonra da İşlevsel Programlama biçiminde yerine getirerek işlevsel programlamanın ne yaptığını / karşılaştırdığını gösterebilir.

Öğrenmenin korkunç bir yolu olurdu. İşlevsel ve nesne yönelimi oldukça farklı stillerdir ve son derece basit olanların dışındaki herhangi bir örnek bir veya diğer stile uymaz.

1 Ancak son zamanlarda kapsamını genel programlamaya genişletmeye çalışıyor, hadi nasıl gidiyor görelim.


Sonuç olarak:

  • Javascript öğrenmeye odaklanın, güzel ve son derece yararlı bir dil. Yutturmaca değil, dili öğrenin.
  • Oldukça farklı paradigmalar, hepsi eşit derecede faydalı. Hangisini tercih edeceğinizi ve hangisinin neyi inşa ederseniz, hangisinin daha uygun olduğunu seçmeniz size kalmıştır.
  • İşlevsel programlamayı öğrenmek istiyorsanız, Scheme veya Clojure gibi daha uygun bir dil seçin . Ancak, öncelikle ilgili matematiksel kavramları anlamanız gerekir.
  • Sormadan önce biraz araştırma yapın. Sorularınızın çoğu ilgili Vikipedi maddeleri tarafından cevaplanmaktadır. Nasıl araştırılacağını ve nasıl sorulacağını bilmek, herhangi bir programcı için son derece önemli bir beceridir.

5
+1 Harika tepki. Programlama eğitiminin yapılandırılmasından dolayı, yeni kodlayıcılar paradigmaların münhasır ve ayrık olduğunu düşünüyorlar, ancak değiller. Bunu yapmak mantıklı olduğunda fonksiyonel kavramlardan yararlanan OOP kodunu yazmaya çalışın. Olay odaklı programlama bir paradigmadır, ancak EDP'nin özellikleri kesinlikle her gui ve web programını etkiler. OOP'nin temel özelliği olan polimorfizm , gerçekten genel bir programlamadır. Bu fikirleri adlandırmak, iyi programlamayı kavramsallaştırmamıza yardımcı olur, ancak birini başkalarının dışlanması için kullanmamalısınız.
kojiro

Her ne kadar orijinal soru ve cevabınız Javascript'i tanımlasa ve işlevsel programlama ile olan ilişkisine rağmen, cevabınız OO ile gördüğüm işlevsel programlama arasındaki en iyi karşılaştırmalardan biri olduğunu düşünüyorum. Aferin.
Başka bir Geliştirici:

“Bu öğrenmenin çok kötü bir yolu olacak.” Bir problem sunan ve OOP ve FP stilleri de dahil olmak üzere bir dizi paradigma ile çözen bu kitabı okumayı yeni bitirdim: github.com/crista/exercises-in-programming-style . Ondan çok şey öğrendim!
Nick

@ Nick Bu sadece size tarif edebilir neyi paradigma oluşacağı ve nasıl çalıştığını, ancak size değil neden tartışmasız en önemli yanı olan. Ama nedenini öğrenmeden önce nasıl olduğunu öğrenmelisin :) bazen bu şeylerin bir süreç olduğunu unuturuz.
Matthew Brent,

8

Javascript işlevsel bir dil olarak kullanılabilir, aslında oldukça iyi yapar. Monadların bir lambda yapısını vb. İçin desteği vardır . Uygulaması mümkündür . Yalnızca çok sayıda nesne yönelimli özelliğine sahip olması ancak işlevsel bir dil değildir, ancak bu şekilde kullanılabilir. Aslında Javascript'i işlevsel bir dil olarak kullanmanın onu kullanmanın harika bir yolu olduğunu buldum. (Örnek jQuery ve underscore.js)


iyi ve özlü! İşlevsel programlamanın genellikle js'de bir şeyler yapmanın en kolay yolu olduğunu kabul etti.
bunglestink

Monadlardan daha da ilginç olanı , okları uygulayabileceğiniz JS'dir ( cs.umd.edu/projects/PL/arrowlets ). Şimdi, neden herkesin JavaScript’de oklar istediğine gelince, bu açık bir soru. Ancak yapılabilir.
Ocak'taki

İşe yarayacaklarını bilmek için okları yeterince anlamadığımı itiraf edeceğim. Fakat Javascript'teki Monad'lar Üzerine Bir Kitap üzerinde çalışıyorum ve Oklar üzerine bir bölüm ekleyebilirim ( shop.oreilly.com/product/0636920023890.do )
Zachary K

6

Evrim normalde artan bir değişim anlamına gelir . OOP, prosedürel programlamaya artımlı bir ek değildir - aslında, temel bir programlama modeline tamamen diktir ve bunlardan herhangi biriyle birleştirilebilir. İşlevsel programlama, işlemsel, OOP ya da her neyse artımlı bir ek değildir - temel bilgi işlem ilkelerini ifade etmek için alternatif bir temeldir ve aslında ilk bilgisayarların ortaya çıkmasından çok önce şimdiye kadar formüle edilmiş ilk temeldir. Tüm bu temel sistemlerin eşdeğer olduğunu anlamak önemlidir (yani bir diğeri açısından ifade edilebilir).

İşlevsel yaklaşımı anlamak için önce temel matematiği almanız gerekir . Javascript'te işlevsel bir tarzda kodlamanın ne anlama geldiğini anlamak istiyorsanız , jQuery kullanmaya başlayın .


2

Yok hayır.

JavaScript her şeyden önce nesne yönelimli bir dildir.

Bu, JavaScript programlarını işlevsel bir stilde yazamayacağınız anlamına gelmez, çünkü yeterince zorlarsanız , herhangi bir Turing tam dilinde işlevsel bir stil uygulayabilirsiniz . İsterseniz assembler içinde fonksiyonel programlama yapabilirsiniz. Ama bu yok değil her dil işlevsel hale. Eşit derecede, Haskell zorunluluğunu veya Java'yı mantıksal bir programlama dili olarak da çağırabilirsiniz - bu yaklaşımı uygularsanız, terimler yakında anlamsız hale gelir.

IMO'ya bir dili uygun paradigmaya göre sınıflandırmanın yolu;

  • Dil yapıları tarafından sağlanan baskın stil nedir (açıkça JavaScript için OOP, işlevsellikler yerine işlevleri ve değişken veri değerlerini vurgular)
  • Dilin temel kütüphanelerinde hangi paradigma desteklenir (yine JavaScript için açıkça OOP)
  • Dilde hangi özellikler devre dışı bırakılır veya önerilmez (işlevsel diller JavaScript için geçerli olmayan değişken değişkenleri yasaklar veya yasaklar)
  • Dili kullanan geliştiriciler topluluğunda hangi gelişim tarzı yaygındır (yine, OOP JavaScript dünyasında açıkça görülmektedir)

Şahsen ben bir dil iddia etmek gibi birçok insan sadece şu anda modaya uygun bir terim çünkü "işlevsel" olduğu gibi eğlenceli buluyorum :-)

Uzun yıllar boyunca paradigmaların programlanması konusunda biraz uzun ama eğlenceli bir bakış açısı istiyorsanız, Bob Amca'nın "The Last Programming Language" adlı videosunu izlemeye değer . Benim için bu konuşmanın en büyük anlayışı, programlama paradigmalarının hangi özellikleri yerine getirdiklerini değil, hangi özellikleri koyduklarını tanımlamalarıydı.


What is the dominant style enabled by the language constructsBunu Perl'e ya da puanlarınızı başkalarına uygulamanıza cüret edersiniz, gerçekten :)
yannis

2
Perl? İyi meydan okuma! İstediğiniz herhangi bir paradigmayı hemen hemen kaldırabileceğiniz anlamında bir tür meclis dili gibi, ancak ortak kullanımda gördüğüm (komut dosyası yazma) çoğunlukla zorunlu / prosedürel bir dil olarak kullanılıyor.
mikera

Oop da oldukça yaygındır. Tabii ki perly bir şekilde. Ve, nadir de olsa işlevseldir . perl sadece perl, bundan bir anlam çıkarmaya çalışmanın bir anlamı yok :)
yannis

JavaScript, Java'dan biraz daha işlevseldir, çünkü en azından kapanması ve birinci sınıf işlevi vardır. Ama senin hakkın, JavaScript, C # kadar işlevsel.
Raynos

2

Javascript, prototip olup, birinci sınıf nesne olarak işlev kullanımı tarafından verilen işlevsel özelliklere sahiptir.

Bu, fonksiyonları, durumu koruyan değişkenlere olan gereksinimi azaltmanın meraklı etkisine sahip veri olarak kullanabileceğiniz anlamına gelir. Kendinizi var ifadesine ulaştığını veya bir veya daha fazla "if" ifadesi kullandığını tespit ederseniz, işlevsel bir tarzdan sapmış olursunuz.

İşlevsel stilin dikkate değer başka bir özelliği, işlevlerin SADECE değerlendirmelerinin sonucunu döndürmesi ve kapsamı dışındaki durum üzerinde hiçbir yan etkisi olmaması gerektiğidir:

// oops, this is producing a side effect
function sideEffecter(){//theres no input...        
    window.thingy = 'foo';
    // hey, this isn't returning anything!!!
} 

İşlevsel diller tahribatsızdır - yani girdiyi mutasyona uğratmazlar, ancak girdiyi temel alan tamamen yeni veriler döndürürler. Bu konuya bakın: https://stackoverflow.com/questions/749084/jquery-map-vs-each

İşlevsel diller aynı zamanda ortak bir çok yönteme sahiptir - "map", "fold", "indirim" gibi isimlerle işlem listelerini / koleksiyonları gösterir. JS'de, diğer dillerden farklı olarak, bunları var olmak zorundayız - bazı örnekler için underscore.js gibi kütüphanelere bakın , ancak JS'nin son uygulaması bunlardan bazılarını doğrudan ortaya çıkardı.

Akılda tutulması gereken önemli şey (IMO), JS'nin bazı fonksiyonel kalıpları kullanabilmesine rağmen, o zaman yürütmek için her zaman iyi donanımlı olmamasıdır.

Örneğin bir dizi üzerinde yineleme yapın. Bunu fonksiyonel bir stil veya yerel döngü yapıları kullanarak yapabilirsiniz - ve genel olarak döngü daha iyi performans gösterir. Bu örneği ele alalım - artan boyutta döngülerle vurun ve yürütme zamanlarını farklı tarayıcılarda kaydedin (bunu zaten yaptım, ancak ölçütleri kaybettim - üzgünüm!):

var test = ['foo', 'bar', 'baz'], removeFunc, removeLoop;

//(semi)functional style...
// to be really functional each condition in the ternary would be another function
removeFunc = function(src, trg) {
    return src.length === 0 ? 
        src : 
            src[0] === trg ? 
                src.slice(1) : 
                    [src[0]].concat(removeFunc(src.slice(1), trg));
};

//but this is faster
removeLoop = function(src, trg){
    var len = src.length, // using variables to represent state...
        i=0, 
        result = [];        
    while(i < n){
       if(src[i] !== trg){
          result.push(src[i]);
       }
       i = i+1;
    }
}

Ek olarak, büyük boyutta halkalara vurmak için işlevsel bir yapı kullanıyorsanız ve bazı özel amaçlı yığın yönetimi yöntemlerini kullanmıyorsanız yığını tıkayabilirsiniz (adil olmak gerekirse, bunun gerçekleşmesi için BÜYÜK bir listeye ihtiyacınız vardır. ..). Ayrıca, her tarayıcıdaki değişken optimizasyonlarını birleştirmek için de etmen gerekiyor - Node.js ortamında çalışıyorsanız, bu açıkça belli bir sabit hedeftir.

Bu, Javascript'te işlevsel yapıları kullanmamanız gerektiği anlamına gelmez - sadece uygulamasında ortamına göre sınırlamaların farkında olun.

İşte ilginizi çekebilecek bazı bağlantılar:

Mükemmel "Eloquent Javascript" in Javascript'teki İşlevsel Programlama üzerine güzel bir bölümü

Küçük Schemer

bir arkadaşım Little Schemer’a dayalı bir JS kütüphanesi yazdı.

Şeması daha iyi anlamanıza yardımcı olacak iyi bir ders

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.