Javascript è un linguaggio di programmazione funzionale


34
  • Javascript è un linguaggio funzionale? So che ha oggetti e puoi anche fare OOP con esso, ma è anche un linguaggio funzionale, può essere usato in quel modo?
  • Sai come OOP è diventato / sembra la prossima evoluzione della programmazione, significa che 'Programmazione funzionale' è la prossima evoluzione (Nota: questo NON è un prompt per l'opinione MA un prompt per una risposta basata su prove fattuali, e questa nota è più per i moderatori che per i collaboratori;)).
  • Imparo meglio attraverso esempi, forse qualcuno potrebbe mostrare di svolgere lo stesso compito in modo OOP e quindi in modo Programmazione funzionale per me stesso per capire e confrontare ciò che la programmazione funzionale fa / è.

In realtà non capisco completamente la "Programmazione funzionale": P Quindi confrontare JavaScript e la programmazione funzionale potrebbe essere totalmente errato.

In parole povere la programmazione funzionale: è semplicemente il beneficio dell'astrazione ATTRAVERSO l'uso di funzioni anonime?

O è troppo semplice? In modo semplice, OOP è il vantaggio dell'astrazione attraverso gli oggetti, ma credo che sia un po 'troppo semplicistico per descrivere OOP.

È un buon esempio di programmazione funzionale? ...

Esempio OOP Javascript:

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

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

Esempio di programmazione funzionale:

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]);

Dipende dalla definizione di "linguaggio di programmazione funzionale". In senso lato, può essere inteso come la capacità di costruire valori funzionali con valori chiusi, ovvero avere un costrutto "lambda" (nel senso del calcolo lambda), e quindi Javascript si adatta al conto.
Basile Starynkevitch il

2
Or is that way too simple?Sì, lo è. Le funzioni anonime sono talvolta associate a linguaggi funzionali e linguaggi multi paradigma che favoriscono la programmazione funzionale, ma non sono una caratteristica unica dei linguaggi funzionali. Ma se li vedi come un'implementazione di λ-calcolo, beh, sono una parte fondamentale della programmazione funzionale, il punto principale è che non è così semplice :)
yannis

Il design di Javascript impedisce alle implementazioni di eseguire l'ottimizzazione delle chiamate in coda. Nei miei libri questo da solo impedisce di essere etichettato come funzionale.
dan_waterworth,

I know it has objects & you can do OOP with it alsoNo, non puoi. È una programmazione basata su prototipi che elimina la distinzione tra classe e oggetto. Personalmente ritengo che la programmazione basata su prototipi sia imperfetta a questo livello di base.
RokL,

Javascript non è un linguaggio funzionale, sicuramente ha caratteristiche funzionali, ma anche un buon vecchio imperativo C, infatti ogni lingua ha le caratteristiche funzionali di base. Un linguaggio funzionale puro, come Haskell, ML, ecc., È un linguaggio dichiarativo, non imperativo.
ALXGTV

Risposte:


72

Javascript è un linguaggio funzionale? So che ha oggetti e puoi anche fare OOP con esso, ma è anche un linguaggio funzionale, può essere usato in quel modo?

A volte, le persone diranno programmazione funzionale, quando ciò che intendono è programmazione imperativa o programmazione procedurale . A rigor di termini, la programmazione funzionale è:

Nell'informatica, la programmazione funzionale è un paradigma di programmazione che considera il calcolo come la valutazione di funzioni matematiche ed evita dati di stato e mutabili . Sottolinea l'applicazione di funzioni, in contrasto con lo stile di programmazione imperativo, che enfatizza i cambiamenti di stato. La programmazione funzionale ha le sue radici nel calcolo lambda, un sistema formale sviluppato negli anni '30 per studiare la definizione della funzione, l'applicazione della funzione e la ricorsione. Molti linguaggi di programmazione funzionale possono essere visti come elaborazioni sul calcolo lambda.

Sebbene Javascript non sia ampiamente conosciuto o utilizzato come linguaggio funzionale, presenta alcuni elementi funzionali :

JavaScript ha molto in comune con Scheme. È un linguaggio dinamico. Ha un tipo di dati flessibile (array) che può facilmente simulare espressioni-s. E, soprattutto, le funzioni sono lambda.

Scheme è un dialetto di Lisp e probabilmente uno dei linguaggi a cui la maggior parte dei programmatori pensa quando discute della programmazione funzionale. Per quanto riguarda l' orientamento agli oggetti , Javascript è un linguaggio orientato agli oggetti. Ma il suo orientamento agli oggetti è basato sul prototipo :

La programmazione basata su prototipi è uno stile di programmazione orientata agli oggetti in cui le classi non sono presenti e il riutilizzo del comportamento (noto come eredità nei linguaggi basati su classi) viene eseguito tramite un processo di clonazione di oggetti esistenti che fungono da prototipi. Questo modello può anche essere noto come programmazione senza classi, orientata ai prototipi o basata su istanze. La delega è la funzione del linguaggio che supporta la programmazione basata su prototipi.

Quindi, sebbene Javascript sia orientato agli oggetti, non segue il modello basato sulla classe più comune , così come i linguaggi come C ++, C #, Java e PHP (e molti altri). E ovviamente è anche un linguaggio imperativo, che porta alla confusione con la programmazione funzionale che ho descritto sopra.

Sai come OOP è diventato / sembra la prossima evoluzione della programmazione, significa che la "Programmazione funzionale" è la prossima evoluzione

L'orientamento agli oggetti e la programmazione funzionale sono solo due dei molti paradigmi di programmazione diversi , sono stili di programmazione diversi con concetti e astrazioni differenti. La parola chiave è "diversa". Non esiste un unico paradigma migliore di altri o più evoluto di altri, ognuno si adatta ad alcuni scenari meglio degli altri. Alcuni possono avere origini molto più antiche di altri, ma in termini evolutivi ciò li rende migliori, poiché sono sopravvissuti più a lungo. Ma non è un modo molto intelligente di vederlo.

Javascript, come ho descritto sopra e alcune altre lingue, è multi-paradigma. Ti permette di scrivere codice in stile imperativo, orientato ai prototipi e orientato agli oggetti. Sta a te scegliere quale si adatta meglio a ciò che stai costruendo. Esistono anche diversi linguaggi a paradigma singolo, l'esempio canonico è Java, che consente solo la programmazione orientata agli oggetti basata su classi 1 .

Dovresti davvero resistere a qualsiasi bisogno di trattare linguaggi e paradigmi come dichiarazioni di moda. C'è un'abbondanza di cazzate là fuori, per lo più scritte da fan / fangirl o persone di marketing, con poca (se presente) conoscenza e comprensione della programmazione. Termini come "migliore", "più evoluto" ecc. Semplicemente non si applicano.

Imparo meglio attraverso esempi, forse qualcuno potrebbe mostrare di svolgere lo stesso compito in modo OOP e quindi in modo Programmazione funzionale per me stesso per capire e confrontare ciò che la programmazione funzionale fa / è.

Sarebbe un modo terribile per imparare. L'orientamento funzionale e dell'oggetto sono stili abbastanza diversi e qualsiasi esempio diverso da quelli terribilmente semplici non si adatterebbe all'uno o all'altro stile.

1 Ma ultimamente tenta di estendere il suo campo di applicazione alla programmazione generica, vediamo come va.


In conclusione:

  • Concentrati sull'apprendimento di Javascript, è un linguaggio bellissimo ed estremamente utile. Impara la lingua, non l'hype.
  • Parecchi paradigmi diversi, tutti ugualmente utili. Spetta a te scegliere quale preferisci e quale si adatta meglio a qualsiasi cosa tu stia costruendo.
  • Se vuoi imparare la programmazione funzionale, scegli un linguaggio più adatto, come Scheme o Clojure . Ma prima devi capire i concetti matematici coinvolti.
  • Fai qualche ricerca prima di chiedere. Alla maggior parte delle tue domande trovano risposta gli articoli pertinenti di Wikipedia. Saper ricercare e chiedere è un'abilità estremamente importante per qualsiasi programmatore.

5
+1 Ottima risposta. A causa del modo in cui è strutturata l'educazione alla programmazione, i nuovi programmatori sembrano pensare che i paradigmi siano esclusivi e discreti, ma non lo sono. Prova a scrivere il codice OOP che sfrutta i concetti funzionali quando ha senso farlo. La programmazione guidata dagli eventi è un paradigma, ma gli aspetti dell'EDP influenzano certamente ogni interfaccia grafica e programma web. Il polimorfismo , una caratteristica fondamentale di OOP, è una programmazione davvero generica. Dare un nome a queste idee ci aiuta a concettualizzare una buona programmazione, ma non dovresti usarne una a esclusione di altre.
Kojiro,

Anche se la domanda originale e la tua risposta descrivono Javascript ed è relativa alla programmazione funzionale, penso che la tua risposta sia uno dei migliori confronti tra OO e programmazione funzionale che ho visto. Molto bene.
AnotherDeveloper,

"Sarebbe un modo terribile per imparare." Ho appena finito di leggere questo libro che presenta un problema e lo risolve con una serie di paradigmi, tra cui gli stili OOP e FP: github.com/crista/exercises-in-programming-style . Ho imparato molto da questo!
Nick,

@ Nick Che può solo descrivere a voi quello che gli sguardi paradigma simile e come funziona, ma non vi dico il motivo , che forse è l'aspetto più importante. Ma devi imparare come prima di sapere perché :) a volte dimentichiamo che queste cose sono un processo.
Matthew Brent,

8

Javascript può essere usato come linguaggio funzionale, infatti lo fa abbastanza bene. È possibile implementare monadi con supporto per un costrutto lambda ecc. Non è esclusivamente un linguaggio funzionale in quanto ha anche molte caratteristiche orientate agli oggetti ma può essere usato in questo modo. In realtà trovo che l'uso di Javascript come linguaggio funzionale sia un ottimo modo per usarlo. (Esempio jQuery e underscore.js)


bravo e conciso! Concordato sul fatto che la programmazione funzionale è spesso il modo più semplice per fare qualcosa in js.
bunglestink,

Ancora più interessante delle monadi, è possibile implementare le frecce è JS ( cs.umd.edu/projects/PL/arrowlets ). Ora, sul motivo per cui qualcuno dovrebbe voler frecce in JavaScript, che è una questione aperta. Ma si può fare.
Persona

Devo ammettere che non capisco abbastanza delle frecce per sapere se saranno utili. Ma sto lavorando a un libro sulle monadi in Javascript e posso aggiungere un capitolo su Arrows ( shop.oreilly.com/product/0636920023890.do )
Zachary K,

6

Evoluzione normalmente significa un cambiamento incrementale . OOP non è un'aggiunta incrementale alla programmazione procedurale - in realtà, è del tutto ortogonale a un modello di programmazione sottostante e può essere combinato con uno qualsiasi di essi. La programmazione funzionale non è un'aggiunta incrementale a procedurale, OOP o altro - è una base alternativa per esprimere i principi di calcolo fondamentali, ed è in realtà la prima base di questo tipo mai formulata, molto prima che apparissero i primi computer. È importante capire che tutti questi sistemi fondamentali sono equivalenti (cioè, uno può essere espresso in termini di un altro).

Per comprendere l'approccio funzionale, devi prima ottenere la matematica di base . Se vuoi avere un'idea di cosa significhi codificare in uno stile funzionale in Javascript, inizia a usare jQuery .


2

No.

JavaScript è innanzitutto un linguaggio orientato agli oggetti.

Questo non vuol dire che non puoi scrivere programmi JavaScript in uno stile funzionale, dal momento che puoi adottare uno stile funzionale in qualsiasi linguaggio completo di Turing se ci provi abbastanza. Se lo desideri, puoi eseguire la programmazione funzionale in assemblatore. Ma questo non rende funzionale ogni lingua. Potresti anche chiamare Haskell imperative o Java un linguaggio di programmazione logica: se avessi adottato questo approccio, i termini diventerebbero presto privi di significato.

IMO il modo per classificare una lingua nel paradigma appropriato è considerare:

  • Qual è lo stile dominante abilitato dai costrutti del linguaggio (chiaramente OOP per JavaScript, i linguaggi funzionali invece enfatizzano funzioni e valori di dati immutabili)
  • Quale paradigma è supportato nelle librerie principali del linguaggio (di nuovo chiaramente OOP per JavaScript)
  • Quali funzionalità sono disabilitate o scoraggiate nella lingua (i linguaggi funzionali scoraggiano o vietano le variabili mutabili, il che non è il caso di JavaScript)
  • Quale stile di sviluppo è prevalente nella comunità di sviluppatori che usano il linguaggio (di nuovo, OOP è chiaramente prevalente nel mondo JavaScript)

Personalmente trovo piuttosto divertente il fatto che a molte persone piace affermare che una lingua è "funzionale" solo perché al momento è un termine alla moda :-)

Se vuoi una prospettiva leggermente lunga ma divertente sui paradigmi di programmazione nel corso degli anni, vale la pena guardare il video dello zio Bob Martin "L'ultimo linguaggio di programmazione" . Per me la grande intuizione di questo discorso è stata che i paradigmi di programmazione sono definiti da quali caratteristiche si tolgono , non da quali caratteristiche mettono in ......


What is the dominant style enabled by the language constructsTi sfido a provare ad applicarlo a Perl ... O a qualsiasi altro dei tuoi punti, davvero :)
yannis

2
Perl? Bella sfida! È un po 'come un linguaggio assembly nel senso che puoi hackerare praticamente qualsiasi paradigma che vuoi insieme, ma nell'uso comune che ho visto (scripting) è usato principalmente come linguaggio imperativo / procedurale.
Mikera,

Bene, anche l'oop è piuttosto comune. In modo perverso, ovviamente. E anche funzionale , anche se non comune. perl è solo perl, non ha senso cercare di dare un senso a ciò :)
yannis

JavaScript è leggermente più funzionale di Java perché almeno ha chiusure e funzioni di prima classe. Ma hai ragione, JavaScript è funzionale quanto C #.
Raynos,

2

Javascript è il primo prototipo, con capacità funzionali - garantito dal suo uso di funzioni come oggetti di prima classe.

Ciò significa che è possibile utilizzare le funzioni come dati, il che ha il curioso effetto di ridurre la necessità di variabili che mantengano lo stato. Se ti accorgi che stai raggiungendo l'istruzione var o stai usando una o più istruzioni "if", allora ti allontani da uno stile funzionale.

Un'altra notevole idiosincrasia dello stile funzionale è che le funzioni dovrebbero SOLO restituire il risultato della loro valutazione e non avere effetti collaterali sullo stato al di fuori del loro ambito:

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

I linguaggi funzionali sono non distruttivi, nel senso che non mutano l'input, ma piuttosto restituiscono dati completamente nuovi basati sull'input. Vedi questa discussione: https://stackoverflow.com/questions/749084/jquery-map-vs-each

I linguaggi funzionali presentano anche molti metodi in comune - con nomi come "map", "fold", "ridurre" che elabora elenchi / raccolte. In JS, a differenza di altre lingue, dobbiamo gestirli manualmente - vedi alcune librerie come underscore.js per alcuni esempi, anche se l'ultima implementazione di JS ne ha alcune immediatamente disponibili.

La cosa importante da tenere a mente (IMO) è che mentre JS può utilizzare alcuni schemi funzionali, non è sempre ben equipaggiato per eseguire allora.

Prendi l'iterazione su un array, ad esempio. Puoi farlo usando uno stile funzionale o i costrutti del ciclo nativo - e in generale il ciclo è più performante. Prendi questo esempio: colpiscilo con anelli di dimensioni crescenti e registra i tempi di esecuzione in diversi browser (l'ho già fatto, ma ho perso i parametri di riferimento - scusa!):

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;
    }
}

Inoltre, se si utilizza un costrutto funzionale per colpire loop di dimensioni considerevoli e non si utilizza una qualche forma di gestione dello stack ad hoc, è possibile inondare lo stack (anche se, per essere onesti, è necessario un elenco GRANDE perché ciò avvenga. ..). Devi anche tener conto del mix delle ottimizzazioni delle varianti in ciascun browser, anche se se lavori in un ambiente Node.js questo è ovviamente più un obiettivo fisso.

Questo non vuol dire che non dovresti usare costrutti funzionali in Javascript - devi solo essere consapevole dei limiti nella sua implementazione rispetto al suo ambiente.

Ecco alcuni link che potrebbero interessarti:

Un buon capitolo sulla programmazione funzionale in Javascript dall'eccellente "Eloquent Javascript"

The Little Schemer

un mio amico ha scritto una libreria JS basata sul Little Schemer

Un buon tutorial su Scheme che potrebbe aiutarti a comprendere meglio FP

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.