Javascript İşlevsel Bir Programlama Dili mi?


135

İşlevler birinci sınıf nesneler olduğu için, kapanışlar ve daha üst düzey işlevler olduğu için, Javascript bir İşlevsel Programlama dili olarak adlandırılmayı hak ediyor mu? Eksik olduğunu düşündüğüm ana şey Saf Fonksiyonlar ve lisp gibi diğer fonksiyonel diller gibi 'hissetmiyor' (işlevsel bir dil olmaması için gerçekten iyi bir neden olmasa da ...)


12
@slashmais: Hayır! Bu sadece onun saf (ly) işlevsel bir dil olmasını engeller. ML (en azından modern lehçeler) de saf değildir - ancak kimse onları işlevsel değil olarak adlandırmaya cesaret edemez;)

4
Yaygın olarak işlevsel olarak kabul edilen, ancak saf olmayan birçok dil vardır. Bunun nasıl bir gereklilik olduğunu anlamıyorum. O kadar katı olmak istiyorsanız, OOP dillerinin çoğu OOP değildir. Sonuçta, tüm dillerin yaklaşık% 95'i paradigma olmayan dillerdir.
jalf

6
Yine de neden önemli? C ++ kod zaman, dil "OOP" olup olmadığını umurumda değil. Belirli OOP özelliklerine sahip olduğunu ve birkaç fonksiyonel programlama özelliğine ve bir çok zorunlu programlama özelliğine ve birçok genel programlama özelliğine sahip olmasını umuyorum. Ama bu bir "OOP" dili mi yoksa bir FP dili mi yoksa başka bir şey mi? Aynı şekilde JS'de kod yazarken, FP olup olmadığı önemli değildir. Önemli olan çok sayıda güzel FP özelliğini desteklemesi. Bu sormak yanlış soru gibi görünüyor.
jalf

3
@hvgotcodes: öyle mi? Kesinlikle söyleyecek bir kural yok. Temel kuralım, işlevsel bir tarzda programlamak için kullanabileceğiniz işlevsel bir dil olmasıdır. Javascript'in birinci sınıf işlevleri, kapanışları ve lambdaları olduğundan, yapabileceğinize inanıyorum ve endişe duyduğum kadarıyla, fonksiyonel bir dil. Açıkçası saf değil, ama tipik olarak FP'yi düşündüğümüz dillerin çoğu da yok (örneğin SML). Yani gerçekten, sadece gevşemeniz gerekiyor. Bu gözünüzü seğirirse, bir doktora görünmeniz gerekir.
jalf

3
@jalf, kesinlikle. Soru için motivasyon, akranlarımın ve benden daha akıllı olan insanların ne düşündüğünü bilmek istedim.
hvgotcodes

Yanıtlar:


180

Benzer bir soruya kendi cevabımı tekrarlayarak ,

İşlevsel programlama dilinin kabul edilmiş bir tanımı yoktur.

İşlevsel dili birinci sınıf işlevleri ve lambdasları destekleyen dil olarak tanımlarsanız, evet, JavaScript * işlevsel bir dildir *.

Değişmezlik desteği, cebirsel veri türleri, kalıp eşleme, kısmi uygulama vb. Gibi faktörleri de dikkate alırsanız, JavaScript * işlevsel bir dil değildir.


Aşağıdaki ilgili blog gönderilerini (ve ayrıca bunların altındaki yorumları) okumanızı tavsiye ederim:


29
Evrensel bir tanım olmadığını ve JS'nin sahip olmadığı arketipik işlevsel dil özelliklerine bazı örnekler getirdiğini göstermek için +1.

1
Mozilla'nın JavaScript uygulamasının sonraki sürümleri (1.7 ile
başlayarak)

JavaScript kısmi ve kısmen parametre uygulama kavramına sahiptir, bu yüzden bunu desteklemediğini ifade etmenin yanlış olup olmadığını merak ediyorum?
johnbakers

2
@OpenLearner, kısmi uygulama düşünebildiğim hemen hemen her dil, hatta C tarafından destekleniyor. JS'deki durum farklı değil. Mesele, kısmi uygulamanın zahmetsiz ve o dilde birinci sınıf olup olmadığıdır. JS'de öyle değil. Ne demek istediğimi merak ediyorsanız, OCaml veya Haskell'e bir göz atın.
missingfaktor

JavaScript değişmezliği destekler.
fka

26

Çok paradigma dili olduğunu söyleyebilirim.

EDIT: Çok paradigma ve fonksiyonel yapılar içerir.


evet, katılıyorum bir karışım ve birkaç farklı şey.
Ashley Grenon

5
ancak bu aynı zamanda işlevsel olup olmadığı sorusuna cevap vermez . Çoklu paradigma olmak çoklu paradigmaları desteklemeyi gerektirir. Bu paradigmalardan biri işlevsel programlama mı?
jalf

15

"işlevsel programlama" terimini felsefi tartışmalar noktasında genişletir ve bükerseniz, bu soru tekrar açık olabilir. Ancak, o zaman "C ++ gerçekten bir programlama dili mi?"

Daha günlük düzeyde sorunuzun cevabı "hayır" dır .

Fonksiyonel programlama, programın bir kontrol akışı yerine bir fonksiyonun değerlendirmesi olarak kavramsallaştırıldığı anlamına gelir. Kod, işlevlerin bir açıklamasıdır ve doğası gereği bir kontrol akışı kavramı yoktur.

JavaScript'in kontrol akışı vardır ve zorunlu bir dil olarak kavramsallaştırılmıştır. Tasarım amacından, açıkça işlevsel bir dil değildir.


1
tasarım hedefi? Ne demek istiyorsun? Son kontrol ettim, ilham kaynaklarından biri de Şema idi. Tasarım hedeflerinden birinin işlevsel programlamanın yanı sıra diğer paradigmaları da desteklemesi olduğunu çok açık söyleyebilirim
jalf

2
Eğer kendiniz için uygun temelleri yazarsanız, C ++ kadar fonksiyonel programlamayı destekler - örneğin, Haskell'de küçük bir çalışma ile zorunlu söz dizimini taklit edebildiğiniz kadar. Bununla birlikte, JavaScript'in sözdizimi, bir fonksiyonun değerlendirilmesi yerine bir iş akışı olarak düşünülmesine yol açar. Bu nedenle, ben (veya çoğu fonksiyonel programcı) "fonksiyonel" terimini çok kapsamlı olarak görmeyi düşünürüm.
shuhalo

@ user411768: Yani bir dilin işlevsel olup olmadığının standart kütüphanesinin tasarımına bağlı olduğunu mu söylüyorsunuz? Bu tanımı daha önce hiç duymamıştım . Java, işlevsel bir tarzda (örneğin, kapaklar ve anonim işlevler) programlamak için gereken araçların çoğuna sahiptir; Ben JS C ++ daha çok FP yapar düşünüyorum. Dilin bir FP tarzında programlamaya zorlamaması onu "daha az işlevsel" yapmaz, değil mi?
jalf

1
(i) Standart kütüphane, tıpkı sözdizimsel özellikler gibi standardın bir parçasıdır ve belirli bir deyimsel ve kavramsal tarzı vurgular. Örneğin, "STL'li C ++", "C'li sınıflar" dan çok farklıdır. Etkisi var. (ii) JavaScript özellikleri nesne yönlendirme, birinci sınıf vatandaş işlevleri - özellikler emperyal / işlevsel ikilik ile oldukça diktir. Bununla birlikte, ne doğrudan körelme uygular ne de saflık sağlamaz ve bunun için hiç tasarlanmamıştır. (iii) Bununla ilgili son sözlerim, yazının ilk paragrafına bakınız.
shuhalo

3
JavaScript ve C ++ 'nın aynı işlevsel programlama kolaylıklarını sunduğu ifadesi kesinlikle yanlıştır. JavaScript, aynı şeyi elde etmek için C ++ 'da geçmeniz gereken dağınık yapılar olmadan fonksiyonel programlamayı oldukça basit ve basit hale getirir. Fonksiyonel programlamanın C ++ 'da gerçekten cesaretlendirilmediğini söyleyen bol miktarda büyük C ++ kodlayıcı vardır, ancak JavaScript'te fonksiyonel programlama yapmaya ilişkin makaleler bol miktarda bulunur
johnbakers

9

"Fonksiyonel programlama" dili bugünlerde o kadar aşırı yüklü ki neredeyse işe yaramaz. İki baskın anlam vardır:

  1. Birinci sınıf fonksiyonları vardır
    • Javascript budur!
  2. Kalıcı değişken durumdan kaçınmaya önem veren lambda hesabında kullanılan işlevlere dayanır (genellikle işlevlere geçirilen parametrelerle değiştirilir)
    • Yaygın olarak yazıldığı gibi, Javascript uzaktan bu değildir!

Anlamını seç ve sonra soru cevaplanabilir.


Birinci sınıf vatandaş olan işlevlere sahip dilleri ifade etmek için "işlevsel programlama" kullanan bir kaynak var mı?
shuhalo

@ user411768: Aslında, Wikipedia'nın bu tanımı kullanan makalesine bağlı başka bir yanıtlayıcı. tr.wikipedia.org/wiki/Javascript - Joel Spolsky de bu tanımı "Programlama diliniz yapabilir mi?" programlama "avantajları üzerine yazı
Chuck

Yaygın olarak yazıldığı gibi, JavaScript'in ikinci noktanızı kullanmadığını, ancak bunun kesinlikle tam olarak bunu yapan programcıların olmadığı ve dilin böyle bir özelliği desteklemediği anlamına gelmediğini unutmayın, çünkü kesinlikle
johnbakers

@OpenLearner: Evet, ama aynı Java ve genellikle kesinlikle şart olarak kabul edilir diğer dillerin kura doğrudur - sen yapabilirsiniz fonksiyonel bir tarzda bunları yazmak, ancak dilin mutlu yolu değil.
Chuck

... ancak en son JS bunu destekleyecekti.
Erik Reppen

3

Fonksiyonel programlamanın somut bir tanımı olduğunu düşünmüyorum, ancak insanların "fonksiyonel programlamayı" düşündüklerinin çoğu javascript ile yapılabilir. İşte bu makalede kısa bir örnek .


2

Bana göre, JavaScript, bir zorunluluk dili ve işlevsel bir dil hem de ve bunu iki şekilde kullanmayı tercih ve hatta (edebilirsiniz egad her iki yönde). Ya da bir paradigmayı kullanmayı seçebilir ve asla diğerine dokunamazsınız. Sana kalmış. Senin gibi Javascript'in bir İşlevsel Dil olarak adlandırılması gerektiğini düşünmüyorum , çünkü işlevsel programlama paradigmasına girip çıkmanıza izin veriyor. Belki bir tür pragması olsaydı, sizi sadece işlevsel programlama paradigmalarını kullanarak sınırlamak, o zaman bu yararlı olurdu, bence. Ancak, özet olarak, bazı fonksiyonel programlama özellikleri ile daha zorunlu / prosedürel bir dil olduğunu düşünüyorum.


Bu muhakemeyle, F # artık işlevsel olarak adlandırılamaz.
Eric Mickelsen

1
Sağ. Wikipedia'ya göre, F # tam olarak Javascript olarak adlandırdığım şey: "F # [...] işlevsel programlama ve zorunlu nesne yönelimli programlama disiplinlerini kapsayan çok paradigma bir programlama dilidir [...]
Brian Onn

2

Programlama dillerinin belirli bir paradigmaya sahip olduğunu düşünmeme eğilimindeyim, ancak belirli paradigmalara borç verdiklerini düşünüyorum. Ancak sadece belirli bir paradigmaya borç vermeleri, bu paradigmayı kullanmanız gerektiği anlamına gelmez. C'ye nesne yönelimli programlar yazmak ve ML'de zorunlu programlar yazmak oldukça mümkündür. Bir sorunu çözmek için belirli bir paradigma kullanmamak, çünkü dil bunun için tasarlanmamıştır, sadece kendinizi yapay olarak sınırlamaktadır (elbette, belirli bir çözümün iyi bir çözüm olup olmayacağına karar verirken bir dilin sınırlamalarını dikkate almalısınız).


0

Bence bu fonksiyonel programlama demezdim ama sonra olur 's nesne yönelimli ve sadece bugün bir arkadaş o ya o rafta koydu söyledi söylüyorlar.

Yani, söyleyemesem de, sanırım görüş için yer var. Fonksiyonel programlamanın klasik özellikleri vardır, başkaları yoktur.


2
JavaScript nesne yönelimlidir. OO sınıf gerektirmez, ancak nesne gerektirir.
Gizli

3
Javascript nesne yönelimli değildir, prototip tabanlıdır.
Kris

1
JavaScript çorba programlıyor. Birazcık, birazcık.
Andrew S

0

Javascript bir noktaya kadar. Gerçekten onu nasıl programladığınıza bağlıdır. OO tarzında kod yazarsam, OO olmaz mıydı? Dolayısıyla, şeyleri 'işlevsel' bir şekilde kodlarsanız, bu işlevsel olacaktır. Sanırım çok paradigma dili bu yüzden sadece tek bir şey demek tamamen doğru değil.


0

Ben kodunuzu bir "yeni" elde etmek için bir az şey yeniden yazmak @petraszd için operatör:

   
   function ffor(a, b, f){
     function it(i){
       if(i > b)return
       f(i)
       it(i+1)
     }
     it(a)
   }

   print("----" + new Date()+"----")

   var funcs = []
   ffor(0, 9, function(i){
     funcs.push(function(){return i})
   })

   ffor(0, 9, function(i){
     print(funcs[i]())
   })

Ama bu yolun büyük döngüler için dezavantajları olduğunu biliyorum ...

JS'de kuyruk tekrarlama optimizasyonu hakkında ilgili soru

PS Burada gönderildi çünkü yorum olarak gönderirken kod biçimlendirme ile ilgili sorun var


0

Javascript'te böyle bir şey yapabilirsiniz !!

// Data
var fruits = [
    { name: 'apple',  price: 5 }, 
    { name: 'orange', price: 10 }, 
    { name: 'lemon',  price: 15 }
]

// Request Data from magicURL
request('magicURL')
    .then(selectKeyOf('price'))
    .then(priceMethod('sum'))
    .then((result)=>{
        console.log(result) // 30
    })

Bu konsepti tanıtmak için bir github sayfası yaptım ve uygulamamı klonlayabilir / görüntüleyebilirsiniz


0

İşlevsel programlama dilinin işlevlerin öğelerini (durumunu) değiştirmesine veya değiştirmesine izin vermediğini bildiğimizden, javascriptte, birinci sınıf vatandaş olarak işlev görmesine rağmen, işlevsel anlamda bir programlama dili olmamasına izin verilmektedir.


-2

Javascript gerçekten nefret (FP dili olarak bakmaya çalışırsanız) şudur:

function getTenFunctionsBad() {
  var result = [];
  for (var i = 0; i < 10; ++i) {
    result.push(function () {
      return i;
    });
  }
  return result;
}

function getTenFunctions() {
  var result = [];
  for (var i = 0; i < 10; ++i) {
    result.push((function (i) {
      return function () {
        return i;
      }
    })(i));
  }
  return result;
}

var functionsBad = getTenFunctionsBad();
var functions = getTenFunctions()
for (var i = 0; i < 10; ++i) {
  // using rhino print
  print(functionsBad[i]() + ', ' + functions[i]());
}

// Output:
//   10, 0
//   10, 1
//   10, 2
//   10, 3
//   10, 4
//   10, 5
//   10, 6
//   10, 7
//   10, 8
//   10, 9

Böyle bir davranışı anlamak için JS yığın ortamını anlamak gerekir (doğru terim değil mi).

Örneğin şemada böyle bir şey üretemezsiniz (Tamam, tamam - altta yatan dillerin referanslarının yardımıyla yapabilirsiniz):

(define (make-ten-functions)
  (define (iter i)
    (cond ((> i 9) '())
          (else (cons (lambda () i) (iter (+ i 1))))))
  (iter 0))

(for-each (lambda (f)
            (display (f))
            (newline)) (make-ten-functions))

1
Hm, bence Javascript değişkene başvuruda bulunuyor ancak değere referansta bulunmuyor .
aeracode

1
Değişken kapsamayı anlamak, her dilde etkili programlama için çok önemlidir. Javascript bu konuda yalnız değil.
zengin remer
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.