Perché l'attuale entusiasmo per la programmazione funzionale? [chiuso]


50

Ultimamente ho sentito molto entusiasmo per i linguaggi di programmazione funzionale, per quanto riguarda Scala, Clojure e F #. Di recente ho iniziato a studiare Haskell, per imparare il paradigma FP.

Lo adoro, è davvero divertente e si adatta al mio background di matematica.

Ma avrà davvero importanza? Ovviamente, non è quasi una nuova idea.

Ecco le mie domande:

  1. Cosa ha contribuito al recente entusiasmo del PQ? È solo la noia con OO o qualcosa è cambiato per rendere FP più necessario di prima?
  2. Questo è indicativo di un futuro FP? O è una moda, come i database orientati agli oggetti?

In altre parole, qualcuno può aiutarmi a capire da dove proviene e dove potrebbe andare?



13
Non un duplicato: questo si sta chiedendo perché le persone improvvisamente stiano facendo storie, dal momento che non è una nuova idea, (mentre quella domanda richiede più differenze oggettive).
Peter Boughton,

2
Le persone stanno facendo storie per la FP ultimamente? Per quanto mi riguarda, ho pensato che questo fosse sempre il caso in cui un gruppo stava facendo storie su come FP avrebbe preso il controllo del mondo della programmazione imperativa.
Chris,

1
Penso di aver già risposto a questa domanda su StackOverflow.
Ken Bloom,

1
Sì, penso che FP fosse già vecchio quando stavo usando Scheme come studente universitario alla Columbia nel 1989. Immagino sia la nuova brillante cosa.
Tim

Risposte:


33

Una delle principali innovazioni in FP che ha provocato la "esplosione" di interesse sono le monadi.

Nel gennaio del 1992, Philip Wadler scrisse un articolo intitolato L'essenza della programmazione funzionale che introduceva le monadi nella programmazione funzionale come un modo per gestire l'IO.

Il problema principale con linguaggi di programmazione puri, pigri e funzionali era l'utilità nel trattare l'IO. È uno dei membri della "Squadra Awkward" nella programmazione, perché "la pigrizia e gli effetti collaterali sono, dal punto di vista pratico, incompatibili. Se si desidera utilizzare un linguaggio pigro, deve essere praticamente un linguaggio puramente funzionale; se vuoi usare gli effetti collaterali, è meglio usare un linguaggio rigoroso. " Riferimento

Il problema con IO prima delle monadi era che il mantenimento della purezza non era possibile per i programmi che erano effettivamente utili per qualsiasi cosa. Per IO intendiamo tutto ciò che riguarda il cambiamento di stato, incluso ottenere input e output dall'utente o dall'ambiente. Nella pura programmazione funzionale, tutto è immutabile, per consentire pigrizia e purezza (senza effetti collaterali).

In che modo le monadi risolvono il problema dell'IO? Bene, senza discutere troppo delle monadi, fondamentalmente prendono il "Mondo" (l'ambiente di runtime) come input per la monade e producono un nuovo "Mondo" come output, e il risultato: digitare IO a = Mondo -> (a, Mondo).

FP è quindi entrato sempre più nel mainstream, perché il problema più grande, IO (e altri) è stato risolto. Anche l'integrazione nelle lingue OO esistenti è avvenuta, come sapete. LINQ è monadi, ad esempio, fino in fondo.

Per maggiori informazioni, raccomando di leggere delle monadi e dei documenti citati nella mia risposta.


Estremamente informativo, grazie. Sto accettando questa risposta, non perché è giusta e gli altri hanno torto (ne ho votati diversi) ma perché penso che meriti la visibilità risultante.
Eric Wilson,

Un esempio più pertinente sarebbe comunque type IO a = UI -> (a, UI)una risposta fantastica.
ChaosPandion,

@Richard: "tipo IO a = Mondo -> (a, Mondo)" sembra quasi troppo bello per essere vero (pensavo che non avrei mai avuto monadi). Immagino che tu abbia paragonato LINQ alle monadi perché quando passi un lambda in un operatore LINQ, il lambda "vede" il suo intero ambiente, giusto?
Stefan Monov,

@Stefan: Sembra abbastanza accurato dire che lambda vede il suo ambiente, ma non sono al 100% chiaro su questo, quindi esito a rispondere fino a quando non imparerò di più da solo. Tuttavia, posso affermare con certezza al 100% che LINQ è monade, perché i creatori lo hanno detto in molte occasioni. SelectMany equivale esattamente a Bind in Haskell. Se non hai letto "The Marvels of Monads " ( blogs.msdn.com/b/wesdyer/archive/2008/01/11/… ) lo consiglio vivamente ... rivelerà come LINQ sia davvero monade. Saluti.
Richard Anthony Hein,

1
@Job, vedi blogs.msdn.com/b/wesdyer/archive/2008/01/11/… come indicato nel commento sopra.
Richard Anthony Hein,

30

Uno dei maggiori problemi durante la programmazione di linguaggi tradizionali come C, Java, C #, assemblatore ecc. È che hai una sequenza imbarazzante di passi che devi compiere per eseguire un determinato compito perché devi prima aver preparato tutte le dipendenze e LE LORO dipendenze prima

Un esempio: per fare A, devi avere B e C presenti, e B dipende da D ed E, risultando in qualcosa di simile

  • D
  • E
  • C
  • B
  • UN

perché devi preparare gli ingredienti prima di poterli usare.

I linguaggi funzionali, specialmente quelli pigri, lo capovolgono. Consentendo ad A di dire che ha bisogno di B e C, e lascia che il runtime della lingua capisca quando ottenere B e C (che a sua volta richiede D ed E), tutti i quali vengono valutati quando è necessario per valutare A, puoi creare molto piccoli e concisi blocchi, che si traducono in programmi piccoli e concisi. I linguaggi pigri consentono anche di utilizzare elenchi infiniti poiché vengono calcolati solo gli elementi effettivamente utilizzati e senza la necessità di memorizzare l'intera struttura di dati in memoria prima di poterlo utilizzare.

Il trucco davvero interessante è che questo meccanismo automatico "oh, ho bisogno di una B e una C" è scalabile perché non ci sono restrizioni - come nel programma sequenziale - su dove e quando questa valutazione può avvenire, quindi può accadere al contemporaneamente e anche su processori o computer diversi.

Ecco perché i linguaggi funzionali sono interessanti - perché il meccanismo "cosa fare quando" viene assunto dal sistema di runtime invece che il programmatore deve farlo manualmente. Questa è una differenza importante tanto quanto la garbage collection automatica era per Java in C, e uno dei motivi principali per cui è più semplice scrivere software multi-thread robusto e scalabile in Java che in C. È anche più facile scrivere robusto, software multi-thread scalabile in linguaggi funzionali ...


3
Questo era vero nel 1950, ovviamente.
Eric Wilson,

1
@FarmBoy, non proprio, ma è oggi.

5
In che cosa differisce dall'iniezione di dipendenza?
Bill K,

2
@ Bill K, eccellente osservazione - non avevo fatto questo collegamento da solo. La differenza è che gli oggetti da iniettare - almeno in Java - vengono valutati con entusiasmo e non valutati pigramente. Non è possibile iniettare un elenco infinito.

1
@ Thorbjørn Ravn Andersen Non sono abbastanza sicuro di capire perché un elenco infinito sarebbe utile, puoi effettivamente fare la somma delle operazioni di tipo (elenco infinito)? Sembra molto improbabile. Altrimenti suona come il modo in cui Java utilizza gli iteratori, basta codificare l'iteratore in modo tale da creare un'istanza degli oggetti solo quando li chiedi - non del tutto infinito, ma infinito (c'è una GRANDE differenza, eh? )
Bill K,

21

Alla fine degli anni '80 / primi anni '90 i computer sono diventati abbastanza potenti per OOP in stile Smalltalk. Oggi i computer sono abbastanza potenti per FP. FP sta programmando a un livello superiore e quindi spesso - sebbene più piacevole da programmare - non il modo più efficiente risolve un certo problema. Ma i computer sono così veloci che non ti interessa.

La pre-elaborazione multi-core può essere più semplice con linguaggi di programmazione puramente funzionali poiché si è costretti a isolare il codice che cambia stato.

Anche i confini del linguaggio di programmazione sono sfocati oggi. Non devi rinunciare a un paradigma se vuoi usarne un altro. Puoi fare FP nelle lingue più popolari, quindi la barriera d'ingresso è bassa.


6
Stavo per aggiungere una risposta, ma hai centrato il mio punto nell'ultima frase; La programmazione funzionale diventerà sempre più diffusa con l'aumentare del numero di core in una singola macchina. L'intrinseca mancanza di stato semplifica la suddivisione meccanica dei programmi funzionali tra i processori (il che significa che se si dispone di un programma puramente funzionale, un compilatore può teoricamente occuparsi del parallelismo per te con il minimo sforzo da parte tua, vedi youtube.com/watch? v = NWSZ4c9yqW8 per una discussione sul parallelismo dei dati).
Inaimathi,

1
@Inaimathi Ditto. La programmazione funzionale è molto scalabile, quindi ha senso su architetture multi-core.
EricBoersma,

Nota che il mio primo commento è stato scritto prima che la risposta fosse modificata per contenere un'ulteriore dichiarazione.
Inaimathi,

Scusa per quello. Ho appena dimenticato questo punto.
LennyProgrammers,

È davvero generalmente accettato che i compilatori funzionali non possano produrre codice macchina ottimizzato come un OOPS? Non riesco a pensare a nessuna ragione teorica per cui questo debba essere vero; e posso pensare a modi in cui sono possibili ottimizzazioni più avanzate rispetto a un OOPS.
Jeremy,

7

Oggi è necessario un calcolo distribuito.

FP utilizza funzioni come blocchi predefiniti, che non hanno stato, quindi invocandole n volte con gli stessi parametri dovrebbe restituire sempre lo stesso valore, non hanno effetti collaterali.

Pertanto, è possibile inviare la stessa funzione a un gruppo di macchine per eseguire e svolgere il lavoro in parallelo.

Nel paradigma OO, questo è un po 'più difficile, perché i blocchi sono oggetti, che sono quasi per definizione stati. Se invochi più volte lo stesso metodo, devi fare attenzione a sincronizzare i dati interni, per evitare il danneggiamento dei dati. Sebbene sia ancora possibile, il paradigma FP funziona meglio dell'OO in alcuni scenari in cui il calcolo deve essere distribuito.

L'avvento di FP (e NoSQL in una certa misura) arriva dopo le storie di incredibili risultati informatici in centinaia di migliaia di computer che lavorano in parallelo e di quanto sia facile.

Ma probabilmente questa è solo una nicchia del tipo di applicazioni che richiedono questo tipo di installazione. Per molte, molte altre applicazioni / sistemi, procedurali e OO funzionano bene.

Quindi sta per espandere i nostri orizzonti di programmazione e riprendere questi concetti che una volta pensavamo non andassero oltre il mondo accademico.

Ho imparato a programmare a Lisp anni fa, e all'epoca non sapevo che fosse nemmeno FP. Ormai ho dimenticato quasi tutto, ma certamente mi aiuta a capire molto facilmente concetti come la ricorsione.


2
La domanda riguarda i vantaggi delle lingue simili a quelle del PQ . Quello che hai descritto può essere fatto anche usando le lingue tradizionali.
Pacerier,

6

Ci stiamo muovendo verso un'era in cui l'elaborazione multi-core non è solo qualcosa di fatto nelle stanze posteriori dei laboratori scientifici o su hardware specializzato. Ora viene fatto con processori di materie prime. La programmazione funzionale, almeno la maggior parte delle varianti a cui sono stato esposto, in genere tenta di dare una visione su unità computazionali stateless libere da effetti collaterali. Questo è il paradigma per eccellenza per il lavoro multi-core in quanto non è necessario mantenere lo stato mescolato tra i processori.

Questo è solo uno dei motivi, ma un dannatamente buono motivo per vedere la programmazione funzionale prendere piede.


5

Penso che la risposta principale a questa domanda sia "l'esposizione".

La programmazione funzionale non è una novità, mi è stato insegnato Haskell all'università circa 12 anni fa e l'ho adorato. Ma raramente devo usare la lingua nel mio lavoro professionale.

Recentemente ci sono state diverse lingue che hanno guadagnato trazione nel flusso principale che usano un approccio multi-paradigma; F # , JavaScript è il primo esempio.

JavaScript in particolare, specialmente se utilizzato con un linguaggio di framework in stile funzionale come jQuery o Prototype , sta diventando un linguaggio quotidiano per molte persone a causa di tutto il lavoro su siti Web dinamici e moderni. Questa esposizione allo stile funzionale fa sì che le persone realizzino il potere che garantisce, specialmente quando si è in grado di tornare a uno stile imperativo a volontà.

Una volta che le persone sono esposte, provano varianti più complete di linguaggi funzionali e iniziano a usarle per le attività quotidiane.

Con F # che diventa un linguaggio di prima classe in Visual Studio 2010 e jQuery (et al) che diventano così importanti, sta diventando realistico usare questi linguaggi, piuttosto che qualcosa di oscuro con cui giocare o creare programmi isolati.

Ricorda che il codice deve essere mantenibile: una massa critica di sviluppatori deve utilizzare e supportare i linguaggi affinché le aziende possano sentirsi al sicuro nel loro utilizzo.


3

In questo discorso Anders Hejlsberg spiega il suo punto di vista sull'argomento.

[MODIFICARE]

Siamo spiacenti, il collegamento era errato. Ora indica il posto giusto.

Riepilogo estremamente breve di alcuni punti del discorso di un'ora:

I linguaggi funzionali consentono uno stile di programmazione più dichiarativo rispetto ai linguaggi procedurali, quindi i programmi scritti in FL di solito si concentrano più sul cosa invece che sul come . Grazie alla loro elegante struttura matematica, i FL sono anche più facili da ottimizzare e trasformare dai compilatori, il che consente anche una facile meta-programmazione e la costruzione di DSL incorporati. Tutto ciò rende i programmi funzionali più concisi e autocompensanti dei programmi procedurali.

Inoltre, di fronte all'era manycore del prossimo futuro, i linguaggi di programmazione devono essere in grado di utilizzare il multi threading / elaborazione in diversi modi. Il multi threading su macchine single core era in effetti un meccanismo di condivisione del tempo, e l'architettura dei sistemi lo rispecchiava. Il multi threading su molti computer core sarà molto diverso. Le lingue funzionali sono particolarmente adatte per la parallelizzazione, poiché evitano principalmente lo stato, quindi non è necessario preoccuparsi tanto dell'integrità dei dati mutabili condivisi (perché non ci sono dati mutabili condivisi).


1
Potresti riassumere?

1
@Thorbjorn Questo mi ricorda l'uomo che non ha potuto riassumere . (Non rivolgendoti a te, rispondi all'autore.)
Marco C,

1
Il collegamento non si collega nemmeno al posto giusto.
Ken Bloom,

2

Penso che abbia a che fare con la stretta correlazione tra il paradigma di programmazione funzionale e la programmazione per il web.

Ruby on Rails ha messo in rilievo l'intero approccio alla programmazione funzionale poiché offriva un percorso molto rapido verso un'applicazione web funzionale (eh eh). C'è un'interessante discussione su SO su questo, e spicca una risposta particolare:

La programmazione funzionale si adatta molto bene alle app Web. L'app Web riceve una richiesta HTTP e produce un risultato HTML. Questa potrebbe essere considerata una funzione dalle richieste alle pagine.

Confronta con le app desktop, in cui in genere abbiamo un processo di lunga durata, un'interfaccia utente con stato e flusso di dati in diverse direzioni. Questo è più adatto a OO che si occupa di oggetti con passaggio di stato e messaggio.

Dato che la programmazione funzionale esiste da secoli, mi chiedo perché non vedo molte inserzioni di lavoro alla ricerca di sviluppatori Lisp per progetti web greenfield.


Penso che l'analogia funzionale si applichi al Web solo per inciso, poiché il protocollo sottostante è apolide. Le applicazioni Web non sono davvero apolidi, il che è in realtà un motivo per cui dobbiamo sempre lavorare in qualche modo attorno a HTTP.
Mladen Jablanović,

@Mladen Hmmm, è possibile che si stiano fondendo lo stato di comunicazione client-server (HTTP) con lo stato dell'applicazione (DAO ecc.)? Citando Stefan Tilkov da qui ( codemonkeyism.com/stateless-applications-illusion ) "In un'applicazione Web ogni singola richiesta dovrebbe contenere informazioni sufficienti per essere processabile indipendentemente dal fatto che si sia verificata o meno una richiesta precedente. Risorsa persistente sul lato server lo stato va bene, lo stato lato client va bene, lo stato della comunicazione transitoria (sessione) non è perché rovinerà la scalabilità e la segnalabilità ". Questa è la base di REST.
Gary Rowe,

1
potresti leggere paulgraham.com/avg.html per capire meglio perché non ci sono molti annunci di lavoro in cerca di sviluppatori Lisp.

@ Thorbjørn Ravn Andersen Buon articolo. Mi ispira a pubblicare il mio editor Lisp.
Gary Rowe,

1

La programmazione funzionale mi dà lo stesso formicolio senso di " wow, questo è nuovo " di quando ho iniziato a dilettarmi con gli oggetti anni fa.

Mi rendo conto che FP non è di gran lunga un nuovo concetto, ma nemmeno lo era OO quando ebbe la sua vera rottura negli anni novanta, quando "tutti" improvvisamente saltarono la nave dalla programmazione procedurale. Ciò è dovuto in gran parte al tempestivo successo di Java e successivamente di C #.

Immagino che alla fine succederà la stessa cosa con FP una volta che il prossimo gruppo di lingue inizierà a diffondersi allo stesso modo. Proprio come hanno già fatto, almeno in alcuni ambienti, con lingue come Scala e F #.


OO è molto più giovane di FP, ma è entrato alla ribalta molto prima. immagino che la parentesi abbia spaventato troppe persone
Javier,

1

Ecco le mie domande: 1. Cosa ha contribuito al recente entusiasmo del PQ? È solo la noia con OO o qualcosa è cambiato per rendere FP più necessario di prima? 2. È indicativo di un futuro PQ? O è una moda, come i database orientati agli oggetti?

Altri hanno dato una buona ragione tecnica.

Penso che il motivo principale per cui FP sta guadagnando trazione tra i tipi medi di sviluppatori e manager sia la promessa di consentire un migliore utilizzo delle CPU multi-core. Da tutto ciò che ho letto FP consente una programmazione parallela più semplice (non facile).

Il suo uso diffuso in futuro sarà se la promessa è reale e viene mantenuta.


Questo è un grande "se". COBOL, essere "in inglese" significava che chiunque poteva programmare. L'intelligenza artificiale avrebbe reso obsoleta la programmazione. OO avrebbe reso la programmazione semplice come assemblare trilli. I programmatori sono come groupie rock, sempre alla ricerca della "prossima grande cosa", e quella successiva, e quella ...
Mike Dunlavey,

0

Penso che sia una combinazione di due tendenze:

  1. Funzioni funzionali aggiunte ai linguaggi tradizionali (ad es. C #).
  2. Nuovi linguaggi funzionali in fase di creazione.

Probabilmente c'è un limite naturale alla prima tendenza, ma la mia ipotesi è che qualsiasi nuovo linguaggio dovrà supportare la programmazione funzionale, almeno come opzione, per essere preso sul serio.


0

In passato le persone scrivevano programmi da eseguire sul desktop usando le API native del sistema operativo e quelle API erano (generalmente) scritte in C, quindi per la maggior parte se volevi scrivere un programma per le API native, tu ha scritto quel programma in C.

Penso che la nuova innovazione negli ultimi 10 anni o giù di lì sia per una varietà di API da cogliere, in particolare per cose come lo sviluppo web in cui le API della piattaforma sono irrilevanti (dal momento che la costruzione di una pagina Web implica sostanzialmente la manipolazione delle stringhe). Dal momento che non stai codificando direttamente all'API Win32 o all'API POSIX, questo offre alle persone la libertà di provare linguaggi funzionali.


0

È bello e carino e solletica il tuo cervello. Va bene.

È anche, IMHO, un classico carrozzone. Una soluzione alla ricerca di un problema.

È come tutte quelle start-up fondate da ingegneri abbagliati con un'idea preferita, che bruciano intensamente per un po ', ma vengono tranquillamente sorpassati da aziende fondate sulla fornitura di ciò che è necessario.

Questa è la nuova idea che vorrei vedere decollare, una programmazione basata sui bisogni, non una programmazione basata su idee ingegnose. Forse sembra banale, ma penso che in effetti possa essere piuttosto creativo e ingegnoso.


-1

Sicuramente a causa di F #, anche se a volte è difficile dire quale sia la causa e quale sia l'effetto.

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.