Javascript è un linguaggio di programmazione funzionale?


135

Solo perché le funzioni sono oggetti di prima classe, ci sono chiusure e funzioni di ordine superiore, Javascript merita di essere chiamato un linguaggio di programmazione funzionale? La cosa principale che penso manchi sono le Pure Functions, e non "sembra" come altri linguaggi funzionali, come lisp (anche se non è proprio una buona ragione per non essere un linguaggio funzionale ...)


12
@slashmais: No! Ciò impedisce solo che sia un linguaggio funzionale puro. Anche i ML (almeno i dialetti moderni) sono impuri - ma nessuno oserebbe chiamarli non funzionali;)

4
Esistono molte lingue comunemente considerate funzionali, ma non pure. Non vedo come sia un requisito. Se vuoi essere così severo, anche la maggior parte dei cosiddetti linguaggi OOP non sono neanche OOP. Si finisce con circa il 95% di tutte le lingue che non sono lingue paradigmatiche.
jalf

6
Perché è importante però? Quando scrivo in C ++, non mi interessa se il linguaggio "è OOP" o no. Mi interessa che abbia alcune funzionalità OOP e che abbia un paio di funzionalità di programmazione funzionale e molte funzionalità di programmazione imperativa e molte funzionalità di programmazione generiche. Ma che sia "un" linguaggio OOP o un linguaggio FP o qualcos'altro non importa. Allo stesso modo quando codice in JS, non importa se si tratta di FP o no. Ciò che conta è che supporta molte belle funzionalità FP. Sembra che questa sia la domanda sbagliata da porre.
jalf

3
@hvgotcodes: così? Non c'è assolutamente alcuna regola dicendo che non lo è. La mia regola empirica è che è un linguaggio funzionale se puoi usarlo per programmare in uno stile funzionale. Poiché Javascript ha funzioni, chiusure e lambda di prima classe, credo che tu possa, e per quanto mi riguarda, è un linguaggio funzionale. Non è puro, ovviamente, ma nemmeno la maggior parte delle lingue che in genere consideriamo FP (SML per esempio). Quindi davvero, penso che devi solo rilassarti. Se questo ti fa contrarre gli occhi, devi consultare un medico.
jalf

3
@jalf, assolutamente. La motivazione della domanda era che volevo sapere cosa pensano i miei colleghi e le persone che sono più intelligenti di me.
hvgotcodes,

Risposte:


180

Ripetendo la mia risposta a una domanda simile,

Non esiste una definizione accettata di linguaggio di programmazione funzionale.

Se definisci il linguaggio funzionale come il linguaggio che supporta le funzioni di prima classe e lambdas, sì, JavaScript * è * un linguaggio funzionale.

Se si considerano anche fattori come il supporto per l'immutabilità, i tipi di dati algebrici, la corrispondenza dei modelli, l'applicazione parziale ecc., Allora JavaScript * non è * un linguaggio funzionale.


Ti incoraggio a leggere i seguenti post di blog correlati (e anche i commenti sottostanti):


29
+1 per sottolineare che non esiste una definizione universale e che fornisce alcuni esempi di funzionalità del linguaggio funzionale archetipico che JS non ha.

1
Le versioni successive dell'implementazione di JavaScript di Mozilla (a partire dall'1.7) presentano una corrispondenza dei modelli sotto forma di incarichi di destrutturazione: developer.mozilla.org/it/New_in_JavaScript_1.7#section_20
jbeard4,

JavaScript ha il concetto di parziali e l'applicazione parziale di parametri, quindi mi chiedo se la tua affermazione che non supporta questo non è corretta?
johnbakers,

2
@OpenLearner, l'applicazione parziale è supportata praticamente da tutte le lingue che mi vengono in mente, anche da C. Per una certa definizione di "supporto" comunque. Il caso con JS non è diverso. Il punto è se l'applicazione parziale è senza sforzo e di prima classe in quella lingua. In JS non lo è. Se sei curioso di sapere cosa intendo, dai un'occhiata a OCaml o Haskell.
missingfaktor,

JavaScript supporta l'immutabilità afaik.
fka,

26

Direi che è un linguaggio multi-paradigma.

EDIT: è multi-paradigma e include costrutti funzionali.


sì, sono d'accordo che è un mix e diverse cose diverse.
Ashley Grenon,

5
ma questo non risponde alla domanda se sia anche funzionale. Essere multi-paradigma implica il supporto di più paradigmi. Uno di questi paradigmi è la programmazione funzionale?
jalf

15

se allunghi e distorci il termine "programmazione funzionale" fino al punto di discussioni filosofiche, questa domanda potrebbe essere di nuovo aperta. Tuttavia, ti ritrovi al livello di domande utili come "Il C ++ è davvero un linguaggio di programmazione"?

La risposta alla tua domanda a un livello più quotidiano è "no" .

La programmazione funzionale significa che il programma è concettualizzato come una valutazione di una funzione, piuttosto che un flusso di controllo. Il codice è una descrizione delle funzioni e non ha un concetto intrinseco di un flusso di controllo.

JavaScript ha un flusso di controllo ed è concettualizzato come linguaggio imperativo. Dal suo obiettivo progettuale, chiaramente non è un linguaggio funzionale.


1
obiettivo di design? Cosa intendi? L'ultima volta che ho controllato, una delle sue fonti di ispirazione era Scheme. Direi che è abbastanza chiaro che uno dei suoi obiettivi progettuali era supportare la programmazione funzionale e un secchio di altri paradigmi
jalf

2
Supporta la programmazione funzionale tanto quanto C ++, se scrivi le basi appropriate per questo da solo - tanto quanto puoi emulare la sintassi imperativa in, diciamo, Haskell con un po 'di lavoro. Tuttavia, la sintassi di JavaScript porta a pensare a un flusso di lavoro piuttosto che alla valutazione di una funzione. Per questa ragione, io (o la maggior parte dei programmatori funzionali) considero l'applicazione del termine "funzionale" come troppo estesa.
shuhalo,

@ user411768: quindi stai dicendo che la funzionalità di una lingua dipende dal design della sua libreria standard? Non ho mai sentito quella definizione prima. Java ha la maggior parte degli strumenti necessari per programmare in uno stile funzionale (chiusure e funzioni anonime, per esempio), che C ++ (attualmente) non ha. Penso che rende JS molto più FP rispetto al C ++. Il fatto che il linguaggio non ti costringa a programmare in stile FP non lo rende "meno funzionale", vero?
jalf

1
(i) La libreria standard fa parte dello standard, proprio come le caratteristiche sintattiche, e sottolinea un certo stile idiomatico e concettuale. Ad esempio, "C ++ con STL" è molto diverso da "C con classi". Ha un impatto. (ii) JavaScript presenta l'orientamento agli oggetti, funzioni di prima classe per i cittadini - le caratteristiche sono piuttosto ortogonali alla dicotomia imperativ / funzionale. Tuttavia, né implementa direttamente il curry, né fornisce purezza, né è mai stato progettato per questo. (iii) Le mie ultime parole al riguardo, vedi il primo paragrafo del post.
shuhalo,

3
L'affermazione che JavaScript e C ++ offrono le stesse comodità di programmazione funzionale è certamente sbagliata. JavaScript rende la programmazione funzionale abbastanza chiara e semplice senza tutti i costrutti disordinati che devi attraversare in C ++ per ottenere la stessa cosa. Ci sono molti grandi programmatori C ++ che affermano in modo evidente che la programmazione funzionale non è davvero incoraggiata in C ++, tuttavia gli articoli su come programmare la programmazione funzionale in JavaScript abbondano
johnbakers

9

Il termine linguaggio di "programmazione funzionale" è così sovraccarico in questi giorni che è quasi inutile. Esistono due significati dominanti:

  1. Ha funzioni di prima classe
    • Javascript è questo!
  2. Si basa sulle funzioni utilizzate nel calcolo lambda, con enfasi sull'evitare lo stato mutabile persistente (spesso sostituendolo con parametri passati alle funzioni)
    • Come comunemente scritto, Javascript non è da remoto questo!

Scegli il tuo significato e quindi la domanda è responsabile.


Esiste una fonte che utilizza la "programmazione funzionale" per riferirsi alle lingue con funzioni che sono cittadini di primo ordine ?.
shuhalo,

@ user411768: In realtà, un altro risponditore è collegato all'articolo di Wikipedia, che utilizza quella definizione. en.wikipedia.org/wiki/Javascript - Joel Spolsky ha anche implicato questa definizione nel suo "Può il tuo linguaggio di programmazione fare questo?" post sui vantaggi della "programmazione funzionale"
Chuck,

Si nota che, come comunemente scritto, JavaScript non utilizza il secondo punto, ma ciò sicuramente non significa che non ci siano programmatori che fanno esattamente questo, e che il linguaggio non supporta tale funzionalità, perché sicuramente lo fa
johnbakers,

@OpenLearner: Beh, sì, ma lo stesso vale per Java e molte altre lingue che sono generalmente considerate strettamente imperative - puoi scriverle in uno stile funzionale, ma non è il percorso felice della lingua.
Chuck,

... ma l'ultimo JS lo supporterebbe.
Erik Reppen,

3

Non credo che ci sia una definizione concreta di programmazione funzionale, tuttavia molte cose che la gente considera "programmazione funzionale" possono essere fatte con javascript. Ecco un breve esempio in questo articolo.


2

Per me, Javascript è sia un linguaggio imperativo che un linguaggio funzionale, e puoi scegliere di usarlo in entrambi i modi e persino ( egad ) in entrambi i modi. Oppure puoi scegliere di usare un paradigma e non toccare mai l'altro. Tocca a voi. Come te, non penso che Javascript debba essere chiamato un linguaggio funzionale, perché ti permette di vagare dentro e fuori dal paradigma della programmazione funzionale. Forse se avesse un pragma di qualche tipo, per limitarti usando solo paradigmi di programmazione funzionale, sarebbe utile, penso. Ma, in sintesi, dico che è più un linguaggio imperativo / procedurale con alcune funzioni di programmazione funzionale integrate.


Con questo ragionamento, F # non può più essere definito funzionale.
Eric Mickelsen,

1
Destra. Secondo Wikipedia, F # è esattamente ciò che ho appena chiamato Javascript: "F # [...] è un linguaggio di programmazione multi-paradigma [...] che comprende la programmazione funzionale e le discipline imperative di programmazione orientata agli oggetti"
Brian Onn

2

Tendo a non pensare ai linguaggi di programmazione come ad avere un paradigma particolare, ma che si prestano a determinati paradigmi. Tuttavia, solo perché si prestano a un particolare paradigma non significa che devi usare quel paradigma. È del tutto possibile scrivere programmi orientati agli oggetti in C e scrivere programmi imperativi in ​​ML. Non usare un certo paradigma per risolvere un problema perché il linguaggio non è progettato per esso sta solo limitando artificialmente te stesso (ovviamente dovresti comunque tenere conto dei limiti di un linguaggio quando decidi se una particolare soluzione sarà una buona soluzione).


0

Beh, non direi che è la programmazione funzionale, ma poi mi sarebbe dire che è orientato agli oggetti e proprio oggi un amico ha detto che non avrebbe messo su quello scaffale sia.

Quindi, anche se non direi che lo sia, credo che ci sia spazio per l'opinione. Ha le caratteristiche classiche della programmazione funzionale, non ne ha altre.


2
JavaScript è orientato agli oggetti. OO non richiede classi, tuttavia richiede oggetti.
Incognito,

3
Javascript non è orientato agli oggetti, è basato sul prototipo.
Kris,

1
JavaScript sta programmando una zuppa. Un po 'di questo e un po' di quello.
Andrew S,

0

Javascript è a un certo punto. Dipende davvero da come procedi per programmarlo. Se codifico in modo OO, non sarebbe OO? Quindi, se semplicemente codifichi le cose in modo "funzionale", sarebbe funzionale. Immagino che sia un linguaggio multi-paradigma, quindi chiamarlo solo una cosa non è del tutto esatto.


0

@petraszd Riscrivo un po 'il tuo codice per ottenere un "nuovo" per l' operatore:

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

Ma so che in questo modo ha degli svantaggi per i grandi loop ...

Domanda correlata sull'ottimizzazione della ricorsione della coda in JS

PS Pubblicato qui perché hanno problemi con la formattazione del codice durante la pubblicazione come commento


0

In Javascript, puoi fare qualcosa del genere !!

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

Ho creato una pagina github per dimostrare questo concetto e puoi clonare / visualizzare la mia implementazione


0

Come sappiamo, il linguaggio di programmazione funzionale non consente di modificare o mutare gli elementi (stato) delle funzioni, ma in javascript è consentito in tal senso che non è un linguaggio di programmazione funzionale, sebbene tratti la funzione come cittadini di prima classe.


-2

Quello che odio davvero in JavaScript (se provi a vederlo come linguaggio FP) è questo:

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

Devi capire l'ambiente dello stack JS (non lo so se è il termine giusto) per capire un simile comportamento.

Nello schema, ad esempio, non puoi semplicemente produrre una cosa del genere (Ok, ok - con l'aiuto dei riferimenti delle lingue sottostanti puoi farlo):

(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, penso che Javascript contenga riferimenti a variabili ma non contenga riferimenti a valore .
codice aereo

1
Comprendere l'ambito variabile è fondamentale per una programmazione efficace in qualsiasi lingua. Javascript non è solo in questo.
rich remer
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.