Quando utilizzare un linguaggio di programmazione funzionale?


90

In quali situazioni dovrei scegliere di utilizzare un linguaggio di programmazione funzionale rispetto a un linguaggio orientato agli oggetti più dettagliato come C ++, C # o Java?

Capisco cos'è la programmazione funzionale, quello che non capisco veramente è per quali tipi di problemi è una soluzione perfetta?


Questa domanda si risponde qui stackoverflow.com/questions/381685/...
krosenvold

2
Sempre. O almeno mai mai.
Shelby Moore III

1
Con lambda, C # è funzionale al limite.
JD

Risposte:


50

I linguaggi funzionali sono, a mio parere, utili principalmente per due cose: IA di gioco e calcoli matematici. È buono nelle IA dei giochi per via delle sue belle manipolazioni di elenchi (almeno in Lisp e Scheme) e per i calcoli matematici a causa della sua sintassi. Scheme, Lisp e Haskell hanno una sintassi che rende i calcoli matematici facili da leggere. L'ultima cosa che devo aggiungere è che i linguaggi funzionali sono linguaggi davvero divertenti. Il mio corso Scheme è stato uno dei corsi con cui mi sono divertito di più.


2
Dopo aver superato il fatto che il mio cervello voleva esplodere nella mia prima settimana del corso di compilatore che ho seguito in Scheme, ho anche trovato che fosse molto divertente (e sono diventato molto più bravo hehe)
Alex Baranosky

1
Quali linguaggi funzionali hai utilizzato per i calcoli matematici?
Jules

8
Inoltre, compilatori! Ho sentito persone che hanno scritto compilatori in Haskell dire che "non scriveranno mai più un compilatore in un linguaggio imperativo".
ShreevatsaR

1
julesjacobs: Ho usato sia haskell che Scheme per risolvere semplici calcoli matematici. Non sono affatto bravo in quelle lingue, quindi ho una strada da percorrere per risolvere problemi più complessi. Non riesco proprio a renderli abbastanza veloci ormai.
martiert

95

Ho fatto alcune ricerche su questo io stesso e ho pensato di aggiungere CONCURRENCY all'elenco dei motivi per utilizzare un linguaggio funzionale. Vedere ad un certo punto nel prossimo futuro la velocità del processore non sarà in grado di aumentare utilizzando la stessa tecnologia della cpu. La fisica dell'architettura non lo permetterà.

Ed è qui che entra in gioco l'elaborazione simultanea.

Sfortunatamente, la maggior parte dei linguaggi OOP non può sfruttare più processori contemporaneamente a causa delle interdipendenze tra i dati.

Nei linguaggi di programmazione puramente funzionali il computer può eseguire due (o molte più) funzioni contemporaneamente perché quelle funzioni non alterano le informazioni di stato esterne.

Ecco un eccellente articolo sulla programmazione funzionale che potrebbe piacerti.


38
Non direi che la maggior parte delle lingue OO non può trarre vantaggio da un numero arbitrariamente elevato di processori. Direi che affinché un programma tragga vantaggio da molti processori contemporaneamente in modo efficiente e affidabile, quel programma deve essere organizzato in modo tale che la maggior parte delle unità di codice ad alta intensità di calcolo si comportino come funzioni pure. È possibile organizzare un programma in questo modo nella maggior parte delle lingue. È più facile farlo nei linguaggi funzionali che nei linguaggi imperativi (compresi i linguaggi orientati agli oggetti).
Zak

2
Grazie per aver collegato quell'articolo. Mi ha davvero aiutato a spiegare le cose.
guptron

13

Un mio amico ha citato uno dei suoi professori universitari dicendo qualcosa del genere:

Disegna una griglia con i tipi di dati nella parte superiore e le operazioni su tali tipi di dati sul lato sinistro. Se affetti la griglia verticalmente, stai facendo OO; se affetti la griglia orizzontalmente, stai facendo FP.

La mia risposta è che FP è un approccio completamente fattibile alla programmazione con un'ampia gamma di applicazioni come OO. Come per qualsiasi discussione sulla scelta del linguaggio di programmazione, penso che le domande più importanti siano:

  1. Hai tempo da investire nell'apprendimento di una nuova notazione e di un nuovo modo di pensare?
  2. Quale delle lingue che stai considerando ha biblioteche sufficientemente ricche da non rimanere bloccato a reinventare qualche ruota?

Per quanto riguarda la prima domanda, se lo stai facendo principalmente per il valore di apprendimento, suggerirei di guardare Haskell , a causa dell'ampia gamma di materiali di supporto (libri, articoli, comunità attiva, ecc.)

Per quanto riguarda la seconda domanda, Haskell ha una buona gamma di librerie (anche se alcune sono più mature di altre), ma Scala (un linguaggio OO-funzionale ibrido in esecuzione sulla JVM) ha i vantaggi che puoi passare più gradualmente allo stile funzionale e hai a disposizione l'intera gamma di librerie accessibili a Java.


Ho imparato Scheme al college, quindi non voglio imparare la programmazione funzionale solo per l'esperienza. Preferisco imparare un linguaggio funzionale per ragioni pratiche.
Alex Baranosky

9

Praticamente tutto quello che puoi fare in PP può essere fatto in FP, e la stessa cosa al contrario. È solo un altro modo per codificare qualcosa: un'altra prospettiva sul problema e un modo diverso per risolverlo.

Tuttavia, poiché non molte persone usano FP, il problema riguarda più la mancanza di buone librerie, la portabilità / manutenibilità (dal momento che il manutentore ha maggiori possibilità di capire qualcosa scritto in C ++ rispetto a Scheme) e la mancanza di documentazione e comunità. So che ci sono alcuni documenti, tuttavia, confrontali con C ++, C # o Java e capirai cosa intendo.

Tuttavia, se vuoi davvero fare FP, puoi usare questo stile anche in C ++ e C #. Ovviamente, non sarà un FP al 100% se usi la libreria standard. Sfortunatamente, non penso che C # sia ottimizzato per essere utilizzato con la programmazione funzionale e probabilmente creerà molti problemi di prestazioni.

Questo è più un post soggettivo, quello che penso di FP. Non è una dichiarazione rigorosa.


8
"Praticamente tutto quello che puoi fare in PP può essere fatto in FP" - In realtà, è esattamente tutto.
BlueRaja - Danny Pflughoeft

2
@BlueRaja - ti riferisci alla completezza di Turing? Se è così, ciò che dici non segue. Ad esempio, Game of Life di Conway è Turing Complete, ma non puoi usarlo per scrivere un driver della scheda video come puoi fare in C. Allo stesso modo non vedo nessuno degli ultimi giochi scritti in Haskell. Può fare in FP! = Potrebbe teoricamente fare in un FP teorico.
Luigi Plinge

@Luigi Plinge dovrei essere d'accordo con BlueRaja. Haskeller che discutono di alcuni driver Linux scritti in Haskell. Non ho un collegamento ma ho anche sentito che un sistema operativo è stato scritto in Haskell (possibili anche altri linguaggi funzionali). Per quanto riguarda i giochi, non vedo gli ultimi giochi scritti in C # o Java, stai insinuando che non possono essere usati per questo? Ad ogni modo, un esempio di un gioco scritto in FP. Inoltre, tieni presente che la maggior parte dei miei link sono Haskell, un linguaggio PURAMENTE funzionale.
austinprete

@PardonMyRhetoric Ovviamente puoi scrivere giochi in Haskell ed eseguire qualsiasi calcolo, ma la velocità sarà parecchie volte più lenta e l'uso della memoria più alto. Quindi un controesempio all'affermazione di BlueRaja sarebbe che non puoi scrivere "un gioco che è veloce e usa quanta memoria è in C" in FP. Questo è un vero problema pratico, non un trucco pedante (e non sono affatto intenzionato a colpire FP - sto programmando Scala in questo momento!).
Luigi Plinge

1
@PardonMyRhetoric Deve anche essere FP idiomatico. I benchmark che vedete che danno prestazioni di Haskell che si avvicinano a quelli di C sono scritti in uno stile unidiomatico di "basso livello" che la maggior parte dei programmatori Haskell non potrebbe scrivere. Ad esempio, potresti ottenere prestazioni simili semplicemente facendo l'output del tuo codice Haskell e compilando il codice C. Inutile però. Una questione pratica correlata è di cosa "puoi fare" rispetto a cosa "puoi / potresti fare". Se qualcosa è semplicemente troppo difficile, non importa molto se è possibile in teoria (e "possibile" per chi?).
Luigi Plinge

4

I linguaggi funzionali sono buoni in molte situazioni. Dipende dalle librerie di un particolare linguaggio funzionale.

Come rispondereste alla domanda "Quando utilizzare un linguaggio di programmazione orientato agli oggetti?"?


1
"Quando utilizzare un linguaggio di programmazione orientato agli oggetti?" Quando vuoi modellare computazionalmente qualsiasi cosa, d'altra parte ho cercato un problema che fp sarebbe la risposta intuitiva, sto ancora cercando, è così che ho trovato questo post.
jimjim

@ Arjang immagino che la programmazione funzionale troverebbe un uso eccezionale nelle applicazioni di calcolo che richiedono solo input per generare output. Nessuna mutabilità e nessuna iterazione
EdgeDev

3

Sebbene questa sia una domanda piuttosto soggettiva, vorrei solo aggiungere che i linguaggi funzionali sono usati molto per analizzare i linguaggi specifici del dominio ; la natura funzionale si presta bene all'analisi delle grammatiche.


2
Analisi DSL? Ho pensato che con le macro Lisp e simili, i DSL sono implementati come macro, non qualcosa che deve essere analizzato dai programmi Lisp. YMMV con linguaggi non Lisp. :-P
Chris Jester-Young

1

Da quello che ho visto, è più una questione di gusto che di funzionalità (nessun gioco di parole). Non c'è davvero nulla in nessuno dei due stili di linguaggio che lo renda intrinsecamente migliore o peggiore in compiti specifici.


2
@ JonHarrop - Ti va di approfondire questo? Non lo trovo così ovvio, e sarebbe un peccato se tu dessi l'impressione che stavi votando le persone per difendersi da meer boosterisim.
TED

1
La famiglia di linguaggi ML è stata creata specificamente per la metaprogrammazione con l'aggiunta di sofisticate caratteristiche del linguaggio come il pattern matching per la manipolazione di alberi (ad esempio, alberi di espressione). Di conseguenza, questa famiglia di lingue è intrinsecamente molto migliore in quel compito specifico.
JD

1
@ JonHarrop - Lo accetto. Tuttavia, stai parlando di ML, non di linguaggi funzionali in generale. Sono un grande sostenitore dei DSL, quindi non discuterò con certezza di utilizzare un linguaggio particolare per il compito esatto per cui è stato progettato.
TED

Oggi, il pattern matching si trova in quasi tutti i linguaggi funzionali inclusi OCaml, F #, Scala, Haskell, Clojure ed Erlang. Ad esempio, di recente ho creato un motore di regole aziendali su misura per un cliente con un focus sulla matematica. Si tratta di 1.000 righe di F # ed è prevalentemente un interprete. Lexing, analisi, controllo del tipo e interpretazione dell'input sono molto più facili grazie alla corrispondenza dei modelli.
JD

@ JonHarrop .. ma non tutti. Non è una caratteristica intrinseca dei linguaggi funzionali, che è ciò di cui si stava chiedendo la domanda.
TED

1

In generale, usa la lingua in cui è più facile esprimere la soluzione a un problema. Per la programmazione funzionale, questo è quando la soluzione a un problema è facilmente espressa in termini di funzioni , da cui il nome. Generalmente va bene per operazioni matematiche, AI, pattern matching; in generale tutto ciò che può essere scomposto in un insieme di regole che devono essere applicate per ottenere una risposta. Puoi determinare la lingua "migliore" da usare solo dopo aver analizzato a sufficienza il tuo problema. È qui che lo pseudo-codice torna utile. Se ti ritrovi a scrivere pseudo-codice che assomiglia a FP, usa FP.

Naturalmente, tutti i linguaggi di programmazione completi sono funzionalmente equivalenti, quindi non importa quale si scelga in termini di problemi che si possono risolvere. Gli effetti principali saranno in termini di efficienza e precisione della codifica e facilità di manutenzione.

Nota anche che è possibile imitare FP nei linguaggi OO attraverso API progettate in modo intelligente. Ad esempio, ho visto numerose librerie Java (JMock è un esempio) che utilizzano il concatenamento di metodi per simulare un FP DSL. Quindi vedrai costrutti come:

logger.expects(once()).method("error") .with( and(stringContains(action),stringContains(cause)) );

Questo essenzialmente costruisce una funzione che viene valutata per determinare se una sequenza di chiamata su un oggetto fittizio è corretta. (esempio rubato da http://www.jmock.org/yoga.html )

Un'altra sintassi simile a FP in linguaggi altrimenti OO è l'uso di chiusure, come in Ruby.


2
"... non importa davvero quale scegli in termini di problemi che puoi risolvere". Solo se hai tempo e denaro infiniti per risolvere il tuo problema.
JD
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.