Apakah Javascript merupakan Bahasa Pemrograman Fungsional?

137

Hanya karena fungsi adalah objek kelas satu, ada closure, dan fungsi tingkat tinggi, apakah Javascript pantas disebut sebagai bahasa Pemrograman Fungsional? Hal utama yang menurut saya kurang adalah Fungsi Murni, dan tidak 'terasa' seperti bahasa fungsional lainnya, seperti cadel (meskipun itu bukan alasan yang baik untuk tidak menjadi bahasa fungsional ...)

hvgotcodes
sumber
12
@slashmais: Tidak! Itu hanya mencegahnya menjadi bahasa fungsional murni. ML (setidaknya dialek modern) juga tidak murni - tetapi tidak ada yang berani menyebutnya tidak berfungsi;)
4
Ada banyak bahasa yang umumnya dianggap fungsional, tetapi tidak murni. Saya tidak melihat bagaimana itu menjadi persyaratan. Jika Anda ingin seketat itu, maka kebanyakan yang disebut bahasa OOP juga bukan OOP. Anda berakhir dengan sekitar 95% dari semua bahasa menjadi bahasa tanpa paradigma.
jalf
6
Mengapa itu penting? Ketika saya membuat kode dalam C ++, saya tidak peduli apakah bahasa "adalah OOP" atau tidak. Saya peduli bahwa ia memiliki fitur OOP tertentu, dan ia memiliki beberapa fitur pemrograman fungsional, dan banyak fitur pemrograman penting, dan banyak fitur pemrograman umum. Tapi apakah itu bahasa OOP "is-a" atau bahasa FP atau yang lainnya tidak masalah. Begitu juga ketika saya membuat kode di JS, tidak masalah apakah itu FP atau tidak. Yang penting adalah ia mendukung banyak fitur FP yang bagus. Sepertinya ini adalah pertanyaan yang salah untuk ditanyakan.
jalf
3
@hvgotcodes: jadi? Sama sekali tidak ada aturan yang mengatakan tidak. Aturan praktis saya adalah bahwa ini adalah bahasa fungsional jika Anda dapat menggunakannya untuk memprogram dalam gaya fungsional. Karena Javascript memiliki fungsi kelas satu, closures dan lambda, saya yakin Anda bisa, dan sejauh yang saya ketahui, ini adalah bahasa fungsional. Bukan bahasa yang murni, jelas, tetapi juga bukan sebagian besar bahasa yang biasanya kami anggap FP (misalnya SML). Jadi sungguh, saya pikir Anda hanya perlu santai. Jika itu membuat mata Anda berkedut, Anda perlu ke dokter.
jalf
3
@ JALAN, tentu saja. Motivasi untuk pertanyaan itu adalah saya ingin tahu apa yang dipikirkan oleh rekan-rekan saya dan orang-orang yang lebih pintar dari saya.
hvgotcodes

Jawaban:

182

Mengulangi jawaban saya sendiri untuk pertanyaan serupa,

Tidak ada definisi bahasa pemrograman fungsional yang diterima.

Jika Anda mendefinisikan bahasa fungsional sebagai bahasa yang mendukung fungsi kelas satu dan lambda, maka ya, JavaScript * adalah * bahasa fungsional.

Jika Anda juga mempertimbangkan faktor-faktor seperti dukungan untuk kekekalan, tipe data aljabar, pencocokan pola, aplikasi parsial, dll. Maka tidak, JavaScript * bukan * bahasa fungsional.


Saya mendorong Anda untuk membaca posting blog terkait berikut (dan juga komentar di bawahnya):

missingfaktor
sumber
30
+1 untuk menunjukkan bahwa tidak ada definisi universal dan membawa beberapa contoh fitur bahasa fungsional pola dasar yang tidak dimiliki JS.
1
Versi implementasi JavaScript Mozilla yang lebih baru (menatap dengan 1.7) memiliki kecocokan pola dalam bentuk tugas penghancuran: developer.mozilla.org/en/New_in_JavaScript_1.7#section_20
jbeard4
JavaScript memiliki pengertian parsial, dan sebagian menerapkan parameter, jadi saya ingin tahu apakah pernyataan Anda bahwa itu tidak mendukung ini salah?
johnbakers
2
@OpenLearner, sebagian aplikasi didukung oleh hampir semua bahasa yang dapat saya pikirkan, bahkan C. Untuk definisi "dukungan" tertentu. Kasus dengan JS tidak berbeda. Intinya adalah apakah penerapan parsial itu mudah dan kelas satu dalam bahasa itu. Di JS, tidak. Jika Anda penasaran dengan apa yang saya maksud, lihat OCaml atau Haskell.
missingfaktor
JavaScript mendukung keabadian afaik.
fka
26

Saya akan mengatakan bahwa ini adalah bahasa multi-paradigma.

EDIT: Ini multi-paradigma dan termasuk konstruksi fungsional.

Niki Yoshiuchi
sumber
ya, saya setuju itu campuran dan beberapa hal yang berbeda.
Ashley Grenon
5
tetapi itu tidak menjawab pertanyaan apakah itu juga berfungsi. Menjadi multi-paradigma berarti mendukung banyak paradigma. Apakah salah satu dari pemrograman fungsional paradigma ini?
jalf
15

jika Anda merentangkan dan memelintir istilah "pemrograman fungsional" ke titik diskusi filosofis, pertanyaan ini mungkin terbuka lagi. Namun, kemudian Anda berakhir pada level pertanyaan berguna seperti "Apakah C ++ benar-benar bahasa pemrograman"?

Jawaban atas pertanyaan Anda pada level harian lainnya adalah "tidak" .

Pemrograman fungsional berarti bahwa program dikonseptualisasikan sebagai evaluasi fungsi, bukan aliran kontrol. Kode ini adalah deskripsi fungsi, dan tidak memiliki konsep aliran kontrol yang melekat.

JavaScript memiliki aliran kontrol dan dikonseptualisasikan sebagai bahasa imperatif. Dari tujuan desainnya, jelas ini bukan bahasa fungsional.

shuhalo
sumber
1
tujuan desain? Apa maksudmu? Terakhir saya periksa, salah satu sumber inspirasinya adalah Skema. Menurut saya, cukup jelas bahwa salah satu tujuan desainnya adalah untuk mendukung pemrograman fungsional serta sekumpulan paradigma lain
jalf
2
Ini mendukung pemrograman fungsional seperti halnya C ++, jika Anda menulis fondasi yang sesuai untuk ini sendiri - sebanyak Anda dapat meniru sintaks imperatif, katakanlah, Haskell dengan sedikit usaha. Namun demikian, sintaksis JavaScript membuatnya dianggap sebagai alur kerja daripada evaluasi suatu fungsi. Oleh karena itu, saya (atau sebagian besar pemrogram fungsional) menganggap penerapan istilah "fungsional" terlalu ekstensif.
shuhalo
@ user411768: jadi maksud Anda apakah suatu bahasa berfungsi atau tidak bergantung pada desain pustaka standarnya? Aku belum pernah mendengar bahwa definisi sebelumnya. Java memiliki sebagian besar alat yang dibutuhkan untuk memprogram dalam gaya fungsional (closures dan fungsi anonim, misalnya), yang tidak dimiliki C ++ (saat ini). Saya pikir itu membuat JS lebih banyak FP daripada C ++. Fakta bahwa bahasa tersebut tidak memaksa Anda untuk memprogram dengan gaya FP tidak membuatnya "kurang berfungsi", bukan?
jalf
1
(i) Pustaka standar adalah bagian dari standar, seperti halnya fitur sintaksis, dan menekankan gaya idiomatik dan konseptual tertentu. Misalnya "C ++ dengan STL" sangat berbeda dengan "C dengan kelas". Ini berdampak. (ii) JavaScript menampilkan orientasi objek, fungsi warga kelas satu - fiturnya agak ortogonal dengan dikotomi imperativ / fungsional. Namun, itu tidak secara langsung menerapkan kari, juga tidak memberikan kemurnian, juga tidak pernah dimaksudkan untuk ini. (iii) Kata-kata terakhir saya tentang itu, lihat paragraf pertama posting.
shuhalo
3
Pernyataan bahwa JavaScript dan C ++ menawarkan kemudahan pemrograman fungsional yang sama tentu salah. JavaScript membuat pemrograman fungsional cukup mudah dan sederhana tanpa semua konstruksi berantakan yang harus Anda lalui di C ++ untuk mencapai hal yang sama. Ada banyak pembuat kode C ++ hebat yang dengan jelas mengatakan bahwa pemrograman fungsional benar-benar tidak dianjurkan dalam C ++, namun artikel tentang melakukan pemrograman fungsional dalam JavaScript berlimpah banyak
johnbakers
9

Istilah bahasa "pemrograman fungsional" sangat berlebihan akhir-akhir ini sehingga hampir tidak berguna. Ada dua arti dominan:

  1. Memiliki fungsi kelas satu
    • Javascript adalah ini!
  2. Didasarkan pada fungsi seperti yang digunakan dalam kalkulus lambda, dengan penekanan pada menghindari status persisten yang dapat berubah (sering kali menggantinya dengan parameter yang diteruskan ke fungsi)
    • Seperti yang biasa ditulis, Javascript bukanlah ini!

Pilih makna Anda dan kemudian pertanyaannya bisa dijawab.

Membuang
sumber
Apakah ada sumber yang menggunakan "pemrograman fungsional" untuk merujuk ke bahasa dengan fungsi sebagai warga negara tingkat pertama ?.
shuhalo
@ user411768: Sebenarnya, penjawab lain tertaut ke artikel Wikipedia, yang menggunakan definisi itu. en.wikipedia.org/wiki/Javascript - Joel Spolsky juga menyiratkan definisi ini dalam "Bisakah bahasa pemrograman Anda melakukan ini?" posting tentang manfaat "pemrograman fungsional"
Chuck
Anda perhatikan bahwa, seperti yang biasa ditulis, JavaScript tidak menggunakan poin kedua Anda, tetapi itu tentu saja tidak berarti bahwa tidak ada programmer yang melakukan hal itu, dan bahasanya tidak mendukung fitur seperti itu, karena memang
johnbakers
@OpenLearner: Ya, tetapi hal yang sama berlaku untuk Java dan banyak bahasa lain yang umumnya dianggap sangat penting - Anda dapat menulisnya dalam gaya fungsional, tetapi itu bukan cara menyenangkan bahasanya.
Chuck
... tapi JS terbaru akan mendukungnya.
Erik Reppen
3

Saya tidak berpikir ada definisi konkret dari pemrograman fungsional, namun banyak hal yang orang anggap sebagai "pemrograman fungsional" dapat dilakukan dengan javascript. Berikut adalah contoh singkat yang bagus di artikel ini .

marknery
sumber
2

Bagi saya, Javascript adalah bahasa imperatif dan bahasa fungsional, dan Anda dapat memilih untuk menggunakannya dengan cara apa pun, dan bahkan ( egad ) keduanya. Atau Anda dapat memilih untuk menggunakan satu paradigma dan tidak pernah menyentuh yang lain. Terserah kamu. Saya, seperti Anda, tidak berpikir Javascript harus disebut Bahasa Fungsional, karena memungkinkan Anda untuk masuk dan keluar dari paradigma pemrograman fungsional. Mungkin jika itu memiliki semacam pragma, untuk membatasi Anda hanya dengan menggunakan paradigma pemrograman fungsional, maka itu akan berguna, saya kira. Namun, secara ringkas, saya mengatakan ini lebih merupakan bahasa imperatif / prosedural dengan beberapa fitur pemrograman fungsional yang dilemparkan.

Brian Onn
sumber
Dengan alasan itu, F # tidak bisa lagi disebut fungsional.
Eric Mickelsen
1
Baik. Menurut Wikipedia, F # persis seperti yang saya sebut Javascript: "F # [...] adalah bahasa pemrograman multi-paradigma [...] yang mencakup pemrograman fungsional serta disiplin pemrograman berorientasi objek yang penting"
Brian Onn
2

Saya cenderung tidak menganggap bahasa pemrograman memiliki satu paradigma tertentu, tetapi mereka meminjamkan diri ke paradigma tertentu. Namun, hanya karena mereka meminjamkan diri pada paradigma tertentu tidak berarti Anda harus menggunakan paradigma itu. Sangat mungkin untuk menulis program berorientasi objek dalam C dan menulis program penting dalam ML. Tidak menggunakan paradigma tertentu untuk menyelesaikan suatu masalah karena bahasanya tidak dirancang untuk itu hanya membatasi diri Anda sendiri secara artifisial (tentu saja Anda harus tetap mempertimbangkan keterbatasan bahasa saat memutuskan apakah solusi tertentu akan menjadi solusi yang baik).

David Brown
sumber
0

Yah, saya tidak akan mengatakan itu pemrograman fungsional, tetapi kemudian saya akan mengatakan itu berorientasi objek dan baru hari ini seorang teman mengatakan dia juga tidak akan meletakkannya di rak itu.

Jadi, meskipun saya tidak akan mengatakannya, saya rasa masih ada ruang untuk opini. Itu memang memiliki fitur klasik dari pemrograman fungsional, tidak ada yang lain.

slezica.dll
sumber
2
JavaScript berorientasi objek. OO tidak membutuhkan kelas, namun membutuhkan objek.
Penyamaran
3
Javascript tidak berorientasi objek, ini adalah berbasis prototipe.
Kris
1
JavaScript adalah sup pemrograman. Sedikit ini dan sedikit itu.
Andrew S
0

Javascript benar. Itu benar-benar tergantung pada bagaimana Anda memprogramnya. Jika saya membuat kode dengan cara OO, bukankah itu menjadi OO? Jadi, jika Anda hanya membuat kode dengan cara 'fungsional', itu akan berfungsi. Saya kira ini adalah bahasa multi-paradigma jadi menyebutnya hanya satu hal tidak sepenuhnya akurat.


sumber
0

@petraszd Saya menulis ulang kode Anda sedikit untuk mendapatkan "baru" untuk operator:

   
   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]())
   })

Tetapi saya tahu bahwa cara ini memiliki kelemahan untuk loop besar ...

Pertanyaan terkait tentang pengoptimalan rekursi ekor di JS

PS Diposting di sini karena bermasalah dengan pemformatan kode saat memposting sebagai komentar

aeracode
sumber
0

Dalam Javascript, Anda dapat melakukan sesuatu seperti ini !!

// 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
    })

Saya telah membuat halaman github untuk mendemonstrasikan konsep ini dan Anda dapat mengkloning / melihat implementasi saya

Wayne Chiu
sumber
0

Seperti yang kita ketahui bahasa pemrograman fungsional tidak memungkinkan untuk mengubah atau mengubah elemen (status) dari fungsi tetapi dalam javascript diperbolehkan dalam arti itu bukan bahasa pemrograman fungsional, meskipun ia memperlakukan fungsi sebagai warga kelas satu.

Sourabh Ranka
sumber
-2

Yang benar-benar saya benci di javascript (jika Anda mencoba melihatnya sebagai bahasa FP) adalah ini:

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

Anda perlu memahami lingkungan tumpukan JS (saya tidak, jika istilah yang tepat) untuk memahami perilaku seperti itu.

Dalam skema misalnya Anda tidak bisa menghasilkan hal seperti itu (Ok, ok - dengan bantuan referensi bahasa yang mendasarinya Anda bisa membuatnya):

(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))
petraszd.dll
sumber
1
Hm, saya pikir Javascript memiliki referensi ke variabel tetapi tidak memiliki referensi ke nilai .
aeracode
1
Memahami pelingkupan variabel sangat penting untuk pemrograman yang efektif dalam bahasa apa pun. Javascript tidak sendirian dalam hal ini.
rich remer