L'apprendimento di un linguaggio funzionale rende un programmatore OOP migliore? [chiuso]


28

Come programmatore Java / C # / C ++ sento parlare molto dei linguaggi funzionali, ma non ho mai trovato la necessità di impararne uno. Ho anche sentito che il più alto livello di pensiero introdotto nei linguaggi funzionali ti rende un OOP / programmatore linguistico procedurale migliore.

Qualcuno può confermare questo? In che modo migliora le tue capacità di programmazione?

Qual è una buona scelta della lingua da imparare con l'obiettivo di migliorare le competenze in una lingua meno sofisticata?


3
Se stai programmando in C #, ne conosci già uno. LINQ è abbastanza funzionale.
SK-logic,

Penso che OOP sia migliore per modellare oggetti della vita reale.
Tulains Córdova,

1
@ user61852 La maggior parte dei modelli di progettazione OO non modella nulla sugli oggetti della "vita reale", ma in realtà concetti altamente astratti.
Andres F.

Essere più di un programmatore Java / C # (+ C ++). C'è una differenza tra un gigantesco coltellino svizzero con un opuscolo non così piccolo che delinea il motivo per cui dovresti selezionare la lama X su 40 e una lama che puoi ritagliare dannatamente vicino a qualsiasi cosa ti piaccia perché è sia dannatamente affilato che solo curve giusto in modo tale da poter applicare il suo potere di taglio a una grande varietà di circostanze senza pensarci troppo. (ovviamente con un apribottiglie nel manico)
Erik Reppen,

Risposte:


32

Sono fondamentalmente d'accordo con la risposta di FrustratedWithFormsDesign , ma è anche chiesto come imparare il nuovo paradigma aiuta a sviluppare le proprie competenze. Posso fare un paio di esempi per esperienza personale.

Dall'apprendimento della programmazione funzionale, sono molto più consapevole di quali concetti con cui lavoro sono più naturalmente considerati come "oggetti" (generalmente dove la mutazione ha un senso) e quali sono più naturalmente considerati "valori" immutabili (penso che ci sia una distinzione importante , toccando dove OO ha senso contro quando FP ha senso, ma questa è solo la mia opinione).

Noto dove il mio codice include effetti collaterali e sono più attento a isolare quei luoghi, rendendo le mie funzioni più "pure". Ciò migliora notevolmente la testabilità del mio codice OO.

Sono più consapevole dei cicli nella mia rappresentazione dei dati. (Ad esempio, non penso che tu possa scrivere una funzione per convertire una lista collegata in una lista doppiamente collegata in Haskell, quindi noti cicli un po 'più in quella lingua.) Evitare cicli riduce la quantità di sincronizzazione devi fare in modo che le tue strutture di dati siano internamente coerenti, alleviando l'onere della condivisione di queste strutture tra thread.

Sono più propenso a fare affidamento sulla ricorsione (i costrutti ciclici ricorsivi dello schema sono cose di bellezza). Dijkstra ha toccato l'importanza di questo in Note sulla programmazione strutturata : gli algoritmi ricorsivi si mappano direttamente all'induzione matematica, che suggerisce sia l'unico mezzo per dimostrare intellettualmente i nostri cicli corretti. (Non suggerisco che dobbiamo dimostrare che il nostro codice è corretto, ma che più facile rendiamo possibile farlo da soli, più è probabile che il nostro codice sia corretto.)

Sono più propenso a utilizzare le funzioni di ordine superiore. Articolo di John Hughes, Perché la programmazione funzionale conta . Sottolinea la componibilità che si ottiene impiegando tecniche di programmazione funzionale, le funzioni di ordine superiore svolgono un ruolo importante.

Inoltre, come accennato nella risposta di Jetti , scoprirai che molte idee FP sono state incorporate nelle nuove lingue OO. Ruby e Python forniscono entrambe molte funzioni di ordine superiore, ho sentito LINQ descritto come un tentativo di portare il supporto per le comprensioni monadiche in C #, anche C ++ ora ha espressioni lambda.


@Aidan: wrt lambdas in C ++ 0x, in ogni caso i nuovi compilatori C ++ li hanno già incorporati.
Matthieu M.

1
"Oggetto" come "cosa che detiene uno stato mutevole" è molto comune, ma il modello Value Object è in circolazione da molti anni.
Frank Shearar,

@Matthieu, grazie, ho aggiornato il testo per riflettere quello.
Aidan Cully,

@Frank: grazie per il puntatore. Non ho incluso questo nella risposta, ma l'obiezione principale che ho di trasformare Values ​​in Objects ha a che fare con la distinzione tra interfacce di oggetti in b / n (che sono di proprietà di oggetti) e operazioni (in cui le relazioni tra gli oggetti sono più primario rispetto agli oggetti stessi). 1 + 2è matematicamente equivalente a 2 + 1, ma 1.+(2)è implementato diversamente da 2.+(1). Esistono numerosi problemi SW che possono essere compresi in modo più naturale utilizzando le operazioni rispetto all'uso delle interfacce degli oggetti.
Aidan Cully,

1
@Aidan Hai letto "Sulla comprensione dell'astrazione dei dati, rivisitato" di William Cook? Approfondisce le differenze tra oggetti e ADT, che è ciò a cui stai accennando.
Frank Shearar,

32

Non direi che è garantito per farti diventare un programmatore OOP migliore, ma ti introdurrà a un nuovo modo di pensare, e questo potrebbe renderti migliore nella risoluzione dei problemi in generale, non solo in termini di OOP.


3
Dato che gli oggetti sono in realtà funzioni di ordine superiore, ho scoperto che apprendere cose FP ha aiutato direttamente con il mio OOP. È, come dici tu, più generalmente applicabile / utile però.
Frank Shearar,

12

Imparare un linguaggio funzionale - Lisp per me - aiuta davvero nella creazione di applicazioni parallele. I metodi funzionali (basati sullo stato, senza effetti collaterali) sono molto più facili da sincronizzare e sono più facili da rendere thread sicuri poiché dipendono solo dal loro input. Ciò significa che i soli dati che devi controllare per una determinata area di codice sono i parametri che passi. Ciò semplifica anche il debug.


Scoprirai che aiuta anche con le librerie di threading, che tendono ad aspettarsi funzioni pure come loro compiti. Può anche aiutare indirettamente, ci sono posti in cui scriverò il codice OO in una sorta di "stile funzionale" in cui esiste un "parametro proprietario" che ha un blocco implicito su un gruppo di oggetti a cui fa riferimento e che vengono utilizzati dalla funzione . Finché documentate le vostre aspettative (e le unit test), questo può darvi un codice multithread migliore con pochi problemi di blocco. E alcuni blocchi espliciti.

Non ho mai sentito parlare di Prolog come un linguaggio funzionale. Se strabico abbastanza posso vedere vagamente come (parti di) Prolog potrebbe aiutare con FP.
Frank Shearar,

1
Prolog non è un linguaggio funzionale. È un linguaggio logico. Se vuoi un linguaggio logico simile a Prolog che sia integrato con la programmazione funzionale, mente, puoi dare un'occhiata a Mercury . Avvertenza: ti farà un po 'male al cervello anche se conosci già Prolog.
SOLO IL MIO OPINIONE corretta

@SOLO IL MIO OPINIONE corretto: Sì, penso che tu abbia ragione. Credo di aver bisogno di saperne di più sui linguaggi funzionali!
Michael K,

1
@moz: Sì, vorrei che Java avesse lambda. Gli Threadoggetti anonimi sono ... goffi.
Michael K,

9

Imparare qualsiasi altro paradigma di programmazione migliorerà le tue capacità di programmazione in generale. La programmazione, quando non è roba accademica di livello di ricerca (e anche allora, spesso), è fondamentalmente la risoluzione dei problemi. Pensando, in una parola. I vari paradigmi sono modi diversi di pensare ai problemi e alle loro soluzioni. Quindi non pensarlo semplicemente come "imparare un linguaggio funzionale". Pensalo come "imparare un modo diverso di pensare ai problemi e alle loro soluzioni". Quindi vedrai i vantaggi dell'apprendimento di una lingua anche se non la usi mai.

Per rispondere alla tua domanda specifica, ero un programmatore C ++ ai tempi passati (prima esisteva uno standard per C ++). Ho seguito tutte le solite cose con oggetti che trattengono lo stato manipolato da metodi, ecc. Ecc. Poi mi sono imbattuto in Haskell e l'ho imparato (molto). (Non credo che nessuno abbia mai davvero imparato Haskell.) L'esercizio sembrava un po 'sprecato in quel momento fino a quando uno dei miei colleghi, il tester assegnato al mio gruppo, ha fatto un commento a mano che il mio codice stava diventando più facile da testare.

Quello che era successo era che avevo iniziato a rendere i miei oggetti sempre più immutabili. Le classi con stato mutabile complesso hanno iniziato a essere sostituite con classi che si sono clonate con modifiche, restituendo i nuovi oggetti. Gli oggetti condivisi hanno iniziato a essere sostituiti con oggetti con semantica copia-scrittura (dando così l'illusione di molti cloni di oggetti senza sovraccarico di memoria). Le funzioni non hanno avuto effetti collaterali se non assolutamente necessario; la pura e matematica definizione di "funzione" era sempre più la norma. Tutto questo ha iniziato ad accadere nel mio codice naturalmente - nessun pensiero cosciente è stato coinvolto - mentre esploravo sempre più lo spazio di programmazione funzionale.

Ora lo scopo di imparare almeno un nuovo paradigma di programmazione ogni due anni (anche se è solo un paradigma di estensione minore come AOP) e almeno due nuove lingue all'interno di ciascun paradigma (uno il più puro possibile, un altro ibrido / pratico ). Ognuno mi ha dato nuovi strumenti intellettuali da applicare a tutta la mia programmazione in qualsiasi lingua, quindi, a mio avviso, il tempo impiegato per impararli non è stato nemmeno leggermente perso.


3

L'ho già detto e lo ripeto, l'apprendimento di linguaggi funzionali ha decisamente migliorato il mio C #. Mi ha aiutato a capire lambdas (e mi ha aiutato ad amarli). Mi ha anche fatto capire quanto preferisco la programmazione funzionale (F #) quando lavoro con operazioni asincrone!


3

Il codice macchina non è altro che un elenco di effetti collaterali: comandi eseguiti direttamente dal processore. Gli effetti collaterali in C sono diversi, piuttosto che gestire i registri e l'hardware fisico, ti occupi di una serie di astrazioni e lascia che il compilatore faccia tutto il lavoro sporco. C ti permette anche di strutturare i tuoi effetti collaterali in loop e in caso affermazioni. C ++ migliora C aggiungendo OOP e alcune funzionalità molto necessarie al linguaggio. Java e C # aggiungono garbage collection e Python aggiunge la digitazione dinamica.

Anche con tutte queste caratteristiche - digitazione dinamica, garbage collection, ecc. I programmi in queste lingue sono ancora interamente basati su effetti collaterali. I linguaggi di programmazione funzionale, come Scheme, Clojure, Haskell e ML sono qualcosa di completamente diverso, questi linguaggi sono più vicini alla matematica che al codice della macchina. Invece, usando gli effetti collaterali, si passano valori attorno alle funzioni.

Qual è una buona scelta della lingua da imparare con l'obiettivo di migliorare le competenze in una lingua meno sofisticata?

Raccomando Scheme , è minimo ed è stato utilizzato nelle vecchie lezioni introduttive di programmazione del MIT. Gli altri linguaggi di programmazione funzionale sono molto più difficili da imparare. Clojure porta con sé tutte le complessità di Java, ML porta con sé un complicato sistema di tipo statico, Haskell viene talvolta definito un linguaggio accademico - non è l'ideale per i principianti, e così via. Lo schema d'altra parte è facile da imparare e capire.

In che modo migliora le tue capacità di programmazione?

Quasi tutti i linguaggi di programmazione di alto livello hanno funzioni e ricorsione - i concetti su cui si basa la programmazione funzionale. Come tale la tua conoscenza di FP dovrebbe essere utile quasi ovunque, tuttavia, se vuoi davvero programmare in modo funzionale, dovresti usare una lingua in cui è naturale ed efficiente piuttosto che cercare di piegare il design linguistico di qualcun altro a tuo piacimento, vale a dire è necessario utilizzare un linguaggio di programmazione funzionale per eseguire la programmazione funzionale.

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.