Ho sentito parlare molto dell'uso di linguaggi funzionali come Haskell negli ultimi tempi. Quali sono alcune delle grandi differenze, pro e contro della programmazione funzionale rispetto alla programmazione orientata agli oggetti?
Direi che è più Programmazione funzionale vs Programmazione imperativa .
La più grande differenza è che la programmazione imperativa riguarda il flusso di controllo mentre la programmazione funzionale riguarda il flusso di dati . Un altro modo per dirlo è che la programmazione funzionale usa solo espressioni mentre nella programmazione imperativa vengono utilizzate sia le espressioni sia le istruzioni .
Ad esempio, in imperativo le variabili di programmazione e i loop sono comuni quando si gestisce lo stato, mentre nella funzionale programmazione lo stato viene gestito tramite il parametro passing, che evita effetti collaterali e assegnazioni.
Pseudo-codice imperativo per una funzione per calcolare la somma di una lista (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 Taming Effects with Functional Programming di Simon Peyton -Jones per una buona introduzione ai concetti funzionali.
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 impaziente e immutabilità.
Se non altro, l'apprendimento della programmazione funzionale è utile per i concetti che contiene. Cambierà il tuo modo di programmare e pensare alla programmazione. E suppongo che in futuro la programmazione funzionale sarà tanto importante quanto la programmazione orientata agli oggetti.
Per iniziare puoi scegliere di usare un puro linguaggio funzionale come Haskell, oppure puoi usare uno ibrido come F # .
Le migliori università copriranno la programmazione funzionale e se vai a scuola ti consiglio caldamente di seguire quel corso.
What are some of the big differences, pros and cons of functional programming vs. object-oriented programming?
La programmazione orientata agli oggetti è utile perché consente di modellare il problema complesso in gerarchie in modo da semplificare il problema. Ma diventa molto difficile quando si inizia a considerare la programmazione multi-thread mentre si usano oggetti mutabili. In questi casi è necessario utilizzare pesantemente gli 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 facile parallelizzare qualcosa quando si sa che dato l'input X a una funzione verrà sempre emesso Y. Inoltre si sa che una variabile (o un valore nella programmazione funzionale) non può cambiare a metà utilizzo da un altro thread.
(Questa risposta è adattata da una risposta a una domanda chiusa a StackOverflow .)
Una delle grandi differenze tra la programmazione funzionale e la programmazione orientata agli oggetti è che ognuno è migliore per un diverso tipo di evoluzione del software:
I linguaggi orientati agli oggetti sono utili quando si ha un insieme fisso di operazioni su cose e man mano che il codice si evolve, si aggiungono principalmente nuove cose. Questo può essere ottenuto aggiungendo nuove classi che implementano metodi esistenti e le classi esistenti vengono lasciate in pace.
I linguaggi funzionali sono utili quando si ha un insieme fisso di cose e man mano che il codice si evolve, si aggiungono principalmente nuove operazioni su cose esistenti. Questo può essere ottenuto aggiungendo nuove funzioni che calcolano con tipi di dati esistenti e le funzioni esistenti sono lasciate in pace.
Quando l'evoluzione va nel modo sbagliato, 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 cosa a un programma funzionale può richiedere la modifica di molte definizioni di funzioni per aggiungere un nuovo caso.
Questo problema è noto da molti anni; nel 1998, Phil Wadler lo soprannominò il "problema dell'espressione" . Sebbene alcuni ricercatori ritengano che il problema delle espressioni possa essere affrontato con caratteristiche linguistiche come i mixin, una soluzione ampiamente accettata non ha ancora raggiunto il mainstream.
Non esiste un vero contro. Possono essere perfettamente complementari. Esistono linguaggi FP, che supportano l'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 preferisci le prove per dimostrare la conformità con le loro leggi.
Nell'imperativo OOP gli utenti tendono a catturare il comportamento dell'oggetto nei casi di test, che può essere rieseguito se l'oggetto è cambiato e ottenere in questo modo la modularità.
È solo un piccolo aspetto, ma penso che sia degno di nota.
Un'analogia:
Ti viene consegnata una domanda di lavoro. Inserisci il tuo nome, le informazioni di contatto e la cronologia di lavoro. Quando hai finito non hai più un'applicazione vuota.
Ora immagina invece che prima di scriverci si sovrapponga ad un foglio trasparente di cellophane. Scrivi il tuo nome. Aggiungi un altro foglio di cellophane. Scrivi le tue informazioni di contatto. Più cellophane. Scrivi la tua cronologia di lavoro. Quando hai finito, hai ancora l'applicazione vuota intatta. Hai anche tre fogli di cellophane ciascuno che hanno catturato l'effetto di un singolo, discreto cambiamento.
Il primo (OOP) abbraccia l'idea di cambiare le cose sul posto mentre il secondo (FP) lo evita. Entrambi sono paradigmi di gestione dello stato. Entrambi possono, utilizzando strategie diverse, cogliere l'effetto di completare un'applicazione di lavoro. OOP cambia direttamente lo strumento di partenza, mentre FP sovrappone quello che prima era per modificare l'aspetto del cambiamento .
Leggi altre domande sui tag object-oriented functional-programming