Risposta:
Wikipedia ha un ottimo articolo sulla programmazione funzionale con alcuni degli esempi che chiedi. @Konrad Rudolph ha già fornito il link all ' articolo OOP .
Non penso che un paradigma sia un super-set dell'altro. Sono diversi punti di vista sulla programmazione e alcuni problemi sono meglio risolti da una prospettiva e alcuni da un'altra.
La tua domanda è ulteriormente complicata da tutte le implementazioni di FP e OOP. Ogni lingua ha le sue peculiarità che sono rilevanti per ogni buona risposta alla tua domanda.
Rambling sempre più tangenziali:
Mi piace l'idea che un linguaggio come Scala cerchi di darti il meglio di entrambi i mondi. Sono preoccupato che ti dia anche le complicazioni di entrambi i mondi.
Java è un linguaggio OO, ma la versione 7 ha aggiunto una funzione "try-with-resources" che può essere utilizzata per imitare una sorta di chiusura. Qui imita l'aggiornamento di una variabile locale "a" nel mezzo di un'altra funzione, senza renderla visibile a quella funzione. In questo caso la prima metà dell'altra funzione è il costruttore ClosureTry () e la seconda metà è il metodo close ().
public class ClosureTry implements AutoCloseable {
public static void main(String[] args) {
int a = 1;
try(ClosureTry ct = new ClosureTry()) {
System.out.println("Middle Stuff...");
a = 2;
}
System.out.println("a: " + a);
}
public ClosureTry() {
System.out.println("Start Stuff Goes Here...");
}
/** Interface throws exception, but we don't have to. */
public void close() {
System.out.println("End Stuff Goes Here...");
}
}
Output:
Start Stuff Goes Here...
Middle Stuff...
End Stuff Goes Here...
a: 2
Questo potrebbe essere utile per lo scopo previsto di aprire un flusso, scrivere nello stream e chiuderlo in modo affidabile, o semplicemente accoppiare due funzioni in modo da non dimenticare di chiamare il secondo dopo aver fatto qualche lavorare tra di loro. Certo, è così nuovo e insolito che un altro programmatore potrebbe rimuovere il blocco try senza rendersi conto che stanno rompendo qualcosa, quindi è attualmente un tipo di anti-pattern, ma interessante che possa essere fatto.
Puoi esprimere qualsiasi loop nella maggior parte delle lingue imperative come una ricorsione. Oggetti e variabili possono essere resi immutabili. Le procedure possono essere scritte per minimizzare gli effetti collaterali (anche se direi che una funzione vera non è possibile su un computer - il tempo necessario per l'esecuzione e il processore / disco / risorse di sistema che consuma sono effetti collaterali inevitabili). Alcuni linguaggi funzionali possono essere creati per eseguire molte, se non tutte, operazioni orientate agli oggetti. Non devono necessariamente escludersi a vicenda, sebbene alcune lingue abbiano limitazioni (come non consentire l'aggiornamento di variabili) che impediscono determinati modelli (come i campi mutabili).
Per me, le parti più utili della programmazione orientata agli oggetti sono l'occultamento dei dati (incapsulamento), il trattamento di oggetti abbastanza simili come lo stesso (polimorfismo) e la raccolta dei dati e dei metodi che operano insieme su tali dati (oggetti / classi) . L'ereditarietà può essere il fiore all'occhiello di OOP, ma per me è la parte meno importante e meno utilizzata.
Le parti più utili della programmazione funzionale sono immutabilità (token / valori anziché variabili), funzioni (senza effetti collaterali) e chiusure.
Non penso che sia orientato agli oggetti, ma devo dire che una delle cose più utili nell'informatica è la capacità di dichiarare un'interfaccia, quindi disporre di varie parti di funzionalità e dati che implementano tale interfaccia. Mi piace anche avere alcuni dati mutevoli con cui lavorare, quindi credo di non essere totalmente a mio agio in linguaggi esclusivamente funzionali, anche se provo a limitare la mutevolezza e gli effetti collaterali in tutti i miei progetti di programma.