Programmazione funzionale vs Programmazione orientata agli oggetti

Sono stato principalmente esposto alla programmazione OO finora e non vedo l’ora di imparare un linguaggio funzionale. Le mie domande sono:

  • Quando scegli la programmazione funzionale rispetto all’object?
  • Quali sono le definizioni tipiche dei problemi in cui la programmazione funzionale è una scelta migliore?

Quando scegli la programmazione funzionale rispetto all’object?

Quando anticipi un diverso tipo di evoluzione del software:

  • I linguaggi orientati agli oggetti sono utili quando si ha un insieme fisso di operazioni sulle 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. Ciò 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 class per aggiungere un nuovo metodo.

  • Aggiungere 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 deve ancora colpire il mainstream.

Quali sono le definizioni tipiche dei problemi in cui la programmazione funzionale è una scelta migliore?

I linguaggi funzionali eccellono nel manipolare i dati simbolici sotto forma di albero. Un esempio preferito sono i compilatori, in cui le lingue di origine e intermedie cambiano raramente (principalmente le stesse cose ), ma gli scrittori di compilatori aggiungono sempre nuove traduzioni e miglioramenti o ottimizzazioni del codice (nuove operazioni sulle cose). La compilazione e la traduzione più in generale sono “app killer” per i linguaggi funzionali.

Non devi necessariamente scegliere tra i due paradigmi. È ansible scrivere software con un’architettura OO utilizzando molti concetti funzionali. FP e OOP sono di natura ortogonale .

Prendi ad esempio C #. Si potrebbe dire che è principalmente OOP, ma ci sono molti concetti e costrutti FP. Se si considera Linq , i costrutti più importanti che consentono a Linq di esistere sono di natura funzionale: espressioni lambda .

Un altro esempio, F #. Si potrebbe dire che è principalmente FP, ma ci sono molti concetti e costrutti OOP disponibili. È ansible definire classi, classi astratte, interfacce, gestire l’ereditarietà. Puoi persino utilizzare la mutabilità quando rende il tuo codice più chiaro o quando aumenta notevolmente le prestazioni.

Molte lingue moderne sono multi-paradigma.

Letture consigliate

Dato che sono nella stessa barca (sfondo OOP, apprendimento FP), ti suggerisco alcune letture che ho davvero apprezzato:

  • Programmazione funzionale per lo sviluppo Everyday .NET , di Jeremy Miller. Un grande articolo (anche se mal formattato) che mostra molte tecniche e esempi pratici reali di FP su C #.

  • Real-World Functional Programming , di Tomas Petricek. Un grande libro che si occupa principalmente di concetti di FP, cercando di spiegare cosa sono, quando dovrebbero essere usati. Ci sono molti esempi sia in F # che in C #. Inoltre, il blog di Petricek è una grande fonte di informazioni.

La programmazione orientata agli oggetti offre:

  1. Incapsulamento, a
    • mutazione del controllo dello stato interno
    • limitare l’accoppiamento alla rappresentazione interna
  2. Sottotipizzazione, consentendo:
    • sostituzione di tipi compatibili (polimorfismo)
    • un mezzo grezzo per condividere l’implementazione tra le classi (ereditarietà dell’implementazione)

La programmazione funzionale, in Haskell o anche in Scala, può consentire la sostituzione attraverso un meccanismo più generale di classi di tipi. Lo stato interno mutevole è scoraggiato o proibito. Si può anche ottenere l’incapsulamento della rappresentazione interna. Vedi Haskell vs OOP per un buon confronto.

L’affermazione di Norman secondo cui “l’aggiunta di un nuovo tipo di cosa a un programma funzionale potrebbe richiedere la modifica di molte definizioni di funzioni per aggiungere un nuovo caso”. dipende da quanto bene il codice funzionale ha impiegato classi di tipi. Se Pattern Matching su un particolare tipo di dati astratti è distribuito su una base di codice, effettivamente soffrirai di questo problema, ma è forse un design scarso per iniziare.

MODIFICATO Rimosso il riferimento alle conversioni implicite quando si discutono le classi di tipi. In Scala, le classi di tipi sono codificate con parametri impliciti, non conversioni, anche se le conversioni implicite sono un altro mezzo per la sostituzione acheiving di tipi compatibili.

  1. Se ci si trova in un ambiente fortemente concorrente, è utile la pura programmazione funzionale. La mancanza di uno stato mutabile rende la concorrenza quasi banale. Vedi Erlang.

  2. In un linguaggio multiparadigm, potresti voler modellare alcune cose dal punto di vista funzionale se l’esistenza dello stato mutabile è necessario un dettaglio di implementazione, e quindi FP è un buon modello per il dominio del problema. Ad esempio, vedi le list comprehensions in Python o std.range nel linguaggio di programmazione D. Questi sono ispirati dalla programmazione funzionale.

La programmazione orientata agli oggetti (OOP) è un paradigma di programmazione basato sul concetto di “oggetti”, che sono strutture di dati che contengono dati, sotto forma di campi, spesso noti come attributi; e codice, sotto forma di procedure, spesso conosciute come metodi.

La programmazione funzionale è un paradigma di programmazione, uno stile di costruzione della struttura e degli elementi dei programmi per computer, che tratta il calcolo come la valutazione delle funzioni matematiche ed evita i dati mutevoli e mutevoli.

OOP dice che unire i dati e il loro comportamento in una singola posizione rende più facile capire come funziona un programma. FP afferma che i dati e il comportamento sono cose distintamente differenti e dovrebbero essere tenuti separati per maggiore chiarezza.

Anche combinando sia la programmazione Javascript che quella orientata agli oggetti, gli sviluppatori possono scrivere codici puliti, concisi e ripetibili. Gli sviluppatori possono creare piccoli blocchi di codici che possono essere richiamati senza dover riscrivere il codice o copiare e incollare il codice più e più volte. OOP JavaScript offre anche un’ereditarietà basata su prototipi, basata su classi, che consente agli oggetti di ereditare direttamente da altri oggetti.