Programmazione funzionale vs. OOP [chiuso]


93

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?


27
Uno non rifiuta un altro.
mbq,

1
@mbq capisco che non si escludono a vicenda, ma volevo solo provare a capire meglio la differenza dei due approcci.
GSto

Ottima domanda Mi stavo chiedendo anche questo.
JohnFx,

La programmazione funzionale e la programmazione orientata agli oggetti sono ortogonali tra loro. Puoi avere entrambi nella stessa lingua. Esempi: Scala, F #, OCaml ecc. Forse intendevi funzionale contro imperativo, come suggerì Jonas ?
missingfaktor,

4
La vera risposta è: non c'è "contro" tra di loro. Dai un'occhiata a questa domanda su StackOverflow .
missingfaktor,

Risposte:


67

Direi che è più programmazione funzionale vs programmazione imperativa .

La differenza principale è che la programmazione imperativa riguarda il flusso di controllo mentre la programmazione funzionale riguarda il flusso di dati . Un altro modo di dire è che la programmazione funzionale utilizza solo espressioni mentre nella programmazione imperativa vengono utilizzate sia espressioni che dichiarazioni .

Ad esempio, nella programmazione imperativa variabili e cicli sono comuni durante la gestione dello stato, mentre nella programmazione funzionale lo stato viene gestito tramite il passaggio di parametri, evitando 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)

Consiglio una presentazione Taming Effects with Functional Programming di Simon Peyton-Jones per una buona introduzione ai concetti funzionali.


12
Dovresti menzionare che la versione funzionale è ricorsiva alla coda e quindi ottimizzata per evitare overflow dello stack. (Alcune persone potrebbero vedere la ricorsione e pensare che la programmazione funzionale sia negativa a causa di ciò)
alternativa

3
+1 per descrivere l'aspetto più importante dell'imperativo vs. funzionale: flusso di controllo vs flusso di dati. Una cosa che devo aggiungere è che il paradigma funzionale e il paradigma OO non si escludono a vicenda; puoi usare il paradigma OO per modellare il modo in cui gli oggetti (dati) interagiscono e il paradigma funzionale per trasformare (manipolare) quell'oggetto.
Lie Ryan,

1
È interessante notare che è possibile modellare i dati come controllo e controllo come dati oltre all'intermix. FP può usare le frecce e le funzioni del primo ordine per passare il flusso di controllo e manipolarlo come dati. OOP utilizza vari modelli di progettazione per utilizzare oggetti per modificare il flusso di controllo.
CodexArcanum,

Penso che valga anche la pena notare che la differenza principale non è che si scrive lo stesso programma ma si effettuano chiamate di metodo ricorsive alla coda. è molto più grande di così
sara

Il tuo esempio funzionale utilizza la corrispondenza dei parametri. Ciò non è esclusivo della programmazione funzionale, allo stesso modo i programmi funzionali possono usare monadi e persino costrutti di tipo imperativo senza necessariamente dover formulare ogni algoritmo iterativo come algoritmo ricorsivo.
Dai,

16

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?

La programmazione orientata agli oggetti è buona 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.


2
Per essere chiari, Scheme non è affatto un linguaggio funzionale puro.
Jonathan Sterling,

5
Il tuo secondo ultimo paragrafo è completamente bs. OO non pone alcun problema nel multithreading, lo fa la mutabilità. Sembri confondere la programmazione imperativa con la programmazione orientata agli oggetti. È così?
missingfaktor,

5
@missingfaktor: No, non confondo i concetti. Un oggetto in genere ha accessori, modificatori, membri di dati e funzioni membro. Sì, non tutti gli oggetti devono avere modificatori e puoi implementarli come immutabili. Ma se si guarda a qualsiasi programma OO arbitrario, quasi sicuramente avrà diversi oggetti che hanno modificatori e tuttavia sono ancora utilizzati da multi thread. Vale a dire in un paradigma OOP è abbastanza raro avere tutto immutabile.
Brian R. Bondy,

Si consiglia di leggere le risposte a questa domanda: stackoverflow.com/questions/3949618/fp-and-oo-orthogonal/...
missingfaktor

Controlla anche la risposta di Frank Shearar qui: programmers.stackexchange.com/questions/12423/…
missingfaktor

8

(Questa risposta è adattata da una 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 utili quando hai un set fisso di operazioni sulle cose e man mano che il tuo 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 nuove 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 ritengano che il problema dell'espressione possa essere affrontato con caratteristiche linguistiche come i mixin, una soluzione ampiamente accettata deve ancora raggiungere il mainstream.


Adoro la tua risposta, parola di saggezza qui. L'ho incontrato qualche mese fa e ho trascorso 30 minuti specificatamente a cercarlo perché non l'ho aggiunto ai segnalibri. Solo la migliore spiegazione su OOP vs FP per coloro che comprendono il vantaggio di comprendere concetti piuttosto che tecniche. Anche il documento sul problema dell'espressione è fantastico. Grazie mille per aver condiviso la tua visione, la mia risposta è molto sottovalutata secondo me.
tobiak777,

4

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

Gli utenti dei linguaggi FP tendono a raggiungere la modularità attraverso leggi matematiche. E preferisce le prove per dimostrare la conformità con le loro leggi.

In OOP imperativo gli utenti 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.


2

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 è accaduto prima per influenzare l'aspetto del cambiamento .


bella analogia, grazie !! ti dispiacerebbe (se possibile) estendere questa analogia con pro e contro in questi due approcci.
Rahul Agarwal,
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.