it-swarm.it

Programmazione funzionale vs. OOP

Recentemente ho sentito parlare molto dell'uso di linguaggi funzionali come Haskell. Quali sono alcune delle grandi differenze, vantaggi e svantaggi della programmazione funzionale rispetto alla programmazione orientata agli oggetti?

95
GSto

Direi che è più Programmazione funzionale vs Programmazione imperativa.

La differenza più grande è che la programmazione imperativa riguarda Flusso di controllo mentre la programmazione funzionale è circa Flusso di dati . Un altro modo di dire è che la programmazione funzionale utilizza solo espressioni mentre nella programmazione imperativa vengono utilizzati entrambi espressioni e istruzioni.

Ad esempio, in imperativo le variabili e i cicli di programmazione sono comuni durante la gestione dello stato, mentre in funzionale la programmazione dello stato viene gestita tramite il passaggio di parametri, che evita effetti collaterali e assegnazioni.

Pseudo-codice imperativo per una funzione per calcolare la somma di un elenco (la somma viene mantenuta in una variabile):

int sumList(List<int> list) {
    int sum = 0;
    for(int n = 0; n < list.size(); n++) {
        sum = sum + list.get(n);
    }

    return sum;
}

Pseudo-codice funzionale per la stessa funzione (la somma viene passata come parametro):

fun sumList([], sum) = sum
 |  sumList(v::lst, sum) = sumList(lst, v+sum)

Raccomando la presentazione Effetti domanti con programmazione funzionale di Simon Peyton-Jones per una buona introduzione ai concetti funzionali.

69
Jonas

La programmazione funzionale si basa su un modello dichiarativo e ha le sue radici dal calcolo lambda. Offre molti grandi concetti che possono essere presi in prestito da linguaggi più imperativi come C++ e C #.

Alcuni esempi includono trasparenza referenziale, funzioni lambda, funzioni di prima classe, valutazione pigra e desiderosa e immutabilità.

Se non altro, l'apprendimento della programmazione funzionale è utile per i concetti che contiene. Cambierà il modo di programmare e pensare alla programmazione. E immagino che in futuro la programmazione funzionale sarà importante tanto quanto lo è stata la programmazione orientata agli oggetti.

Per iniziare puoi scegliere di usare un linguaggio funzionale puro come Haskell, oppure puoi usarne uno ibrido come F # .

La maggior parte delle buone università coprirà la programmazione funzionale e se vai a scuola ti consiglio vivamente di seguire quel corso.


Quali sono alcune delle grandi differenze, vantaggi e svantaggi della programmazione funzionale rispetto alla programmazione orientata agli oggetti?

Anche la programmazione orientata agli oggetti è piacevole perché ti consente di modellare il tuo problema complesso in gerarchie in modo da poterlo semplificare. Ma diventa molto difficile quando inizi a considerare la programmazione multi-thread mentre usi oggetti mutabili. In questi casi è necessario utilizzare un uso intenso di oggetti di sincronizzazione ed è quasi impossibile perfezionare un'applicazione di grandi dimensioni.

È qui che entra in gioco la programmazione funzionale. A causa di cose come l'immutabilità, la programmazione funzionale semplifica davvero i programmi multi-thread. Rende quasi banalmente semplice parallelizzare qualcosa quando sai che dato l'input X a una funzione emetterà sempre Y. Inoltre sai che una variabile (o valore nella programmazione funzionale) non può cambiare a metà uso da un altro thread.

16
Brian R. Bondy

(Questa risposta è adattata da un risposta a una domanda chiusa su StackOverflow .)

Una delle grandi differenze tra la programmazione funzionale e la programmazione orientata agli oggetti è che ognuna è migliore in un diverso tipo di evoluzione del software:

  • I linguaggi orientati agli oggetti sono buoni quando hai un set fisso di operazioni su cose e man mano che il codice si evolve, aggiungi principalmente nuove cose. Ciò può essere ottenuto aggiungendo nuove classi che implementano metodi esistenti e le classi esistenti vengono lasciate sole.

  • I linguaggi funzionali sono buoni quando hai un set fisso di cose , e man mano che il tuo codice si evolve, aggiungi principalmente nuovi operazioni su cose esistenti. Ciò può essere ottenuto aggiungendo nuove funzioni che calcolano con tipi di dati esistenti e le funzioni esistenti vengono lasciate sole.

Quando l'evoluzione va nella direzione sbagliata, hai problemi:

  • L'aggiunta di una nuova operazione a un programma orientato agli oggetti potrebbe richiedere la modifica di molte definizioni di classe per aggiungere un nuovo metodo.

  • L'aggiunta di un nuovo tipo di cose a un programma funzionale potrebbe richiedere la modifica di molte definizioni di funzioni per aggiungere un nuovo caso.

Questo problema è noto da molti anni; nel 1998, Phil Wadler lo ha definito il "problema dell'espressione" . Sebbene alcuni ricercatori pensino che il problema dell'espressione possa essere affrontato con caratteristiche linguistiche come i mixin, una soluzione ampiamente accettata deve ancora raggiungere il mainstream.

10
Norman Ramsey

Non c'è vero contro. Possono essere perfettamente complementari. Esistono FP linguaggi, che supportano OOP. Ma le comunità differiscono nel modo in cui gestiscono la modularità.

Gli utenti delle lingue FP tendono a raggiungere la modularità attraverso le leggi matematiche. E preferiscono le prove per dimostrare la conformità con le loro leggi.

In imperativo OOP tendono a catturare il comportamento dell'oggetto nei casi di test, che possono essere rieseguiti se l'oggetto è cambiato e ottenere così la modularità.

È solo un piccolo aspetto, ma penso che valga la pena menzionarlo.

5
Edgar Klerks

Un'analogia:

Ti viene consegnata una domanda di lavoro. Inserisci il tuo nome, le informazioni di contatto e la cronologia dei lavori. Quando hai finito non hai più un'applicazione vuota.

Ora immagina invece che prima di scriverlo lo ricopri con un foglio di cellophane trasparente. Scrivi il tuo nome. Aggiungi un altro foglio di cellophane. Scrivi le tue informazioni di contatto. Più cellophane. Scrivi la tua storia lavorativa. Quando hai finito hai ancora l'applicazione vuota intatta. Hai anche tre fogli di cellophane ciascuno dopo aver catturato l'effetto di un singolo, discreto cambiamento.

Il primo (OOP) abbraccia l'idea di cambiare le cose sul posto mentre il secondo (FP) la evita. Entrambi sono paradigmi di gestione dello stato. Entrambi possono, usando strategie diverse, catturare l'effetto del completamento di una domanda di lavoro. OOP modifica direttamente lo strumento di partenza, mentre FP sovrappone ciò che era precedente per rendere effettivo l'aspetto del cambiamento .

2
Mario T. Lanza