Come codificare uno stile più funzionale in Java? [duplicare]

15

Io codice Java per almeno 5 anni e apprezzo molto il funzionamento della lingua. Quando si esaminano i nuovi linguaggi JVM (ad esempio Scala, Clojure), esiste una tendenza a modi più funzionali per codificare e in questo modo ha alcuni importanti vantaggi.

Ad ogni modo, ci sono schemi per ottenere uno stile più funzionale anche quando si utilizza Java o un altro OOP puro? E questo ha senso in Java?

    
posta Nils 25.01.2013 - 00:10
fonte

5 risposte

16

La programmazione funzionale ha due qualità principali che la definiscono: enfasi su dati immutabili e funzioni di prima classe. Entrambi sono - con qualche sforzo e ragionevoli - realizzabili in Java.

Puoi certamente avere oggetti immutabili. Stabilire esplicitamente lo stato dell'oggetto tramite il costruttore, non esporre i setter e applicare la parola chiave final ai campi. Ogni volta che si dovrebbe modificare un metodo nello stato interno dell'oggetto, è necessario restituire una nuova istanza con lo stato aggiornato. Un approccio come questo è stato presentato in Real-World Functional Programming , un libro contenente esempi di codice funzionale in F # e corrispondenti codice in C #. Mentre C # è più adatto alla programmazione funzionale rispetto a Java, un approccio simile potrebbe ancora essere applicato a Java.

Quando si tratta di funzioni di prima classe, le cose diventano un po 'più complicate. Al momento Java ha un meccanismo piuttosto goffo e prolisso di emulazione di funzioni che utilizzano classi nidificate anonime, con un supporto limitato per le chiusure. Mentre è sufficiente scrivere almeno alcuni pezzi di codice in uno stile funzionale, sarebbe un'esperienza scialba rispetto all'uso di un linguaggio funzionale appropriato. Sono disponibili librerie Java, in particolare guava , che introducono alcuni concetti di programmazione funzionale in Java, come immutabili collezioni e alcuni idiomi funzionali. Questo probabilmente renderebbe l'esperienza meno raccapricciante, ma anche la documentazione ufficiale per guava afferma che gli idiomi funzionali dovrebbe essere usato con parsimonia, in quanto spesso portano a un codice che è più prolisso, meno chiaro e meno efficiente della corrispondente versione imperativa.

La situazione per Java dovrebbe migliorare con il rilascio di SE 8, impostato per includere chiusure appropriate e espressioni lambda, rimandate da SE 7. Nel frattempo puoi provare uno dei vari linguaggi funzionali di JVM e interop con Java quando necessario .

    
risposta data 25.01.2013 - 01:36
fonte
5

Molti dei modelli di progettazione Gang of Four sono considerati implementare concetti funzionali in un linguaggio orientato agli oggetti.

I modelli di progettazione funzionale sono utili. Anche la serie " Pensiero funzionale ". Entrambi da IBM.

Una presentazione (non l'ho guardato per verificare) su Modelli di design funzionale è riepilogata come

Aino Vonge Corry reviews a number of well known design patterns showing that their implementation is simpler in functional languages because such languages have pattern-based constructs.

All'interno di Java, le chiusure possono essere implementate come classi locali all'interno di un metodo e creare la possibilità di espandersi molto di più nel regno della programmazione funzionale. Java 8 estende questa funzionalità con lambdas.

Quindi, per rispondere alla tua domanda - molti dei modelli di progettazione sono che implementano già i concetti funzionali. E hanno senso in Java.

Se tutto il resto fallisce, puoi sempre invocare la decima regola di Greenspun per ottenere qualsiasi modello funzionale che cerchi.

    
risposta data 25.01.2013 - 00:36
fonte
5

Aggiungendo a ciò che altri hanno già detto qui, nella Programmazione Funzionale c'è un disco per separare il codice che modifica / modifica lo stato degli effetti collaterali dal codice funzionalmente puro e rendere esplicita la separazione. Questo è ottenuto ad es. Haskell attraverso l'uso di IO e Monade di stato e in Clojure attraverso i ref.

Nello stato OOP e le modifiche dello stato sono incapsulate negli oggetti, quindi a meno che non si passi alla rotta degli oggetti immutabili, questo sarà probabilmente un po 'più difficile da fare.

Qualcosa che potrebbe aiutare è seguire il Principio di comando / Query Separation , che afferma che un'operazione dovrebbe essere un comando e causare effetti collaterali, ma non restituire nulla, o dovrebbe essere una query con un valore di ritorno, senza effetti collaterali. Seguire questo principio potrebbe aiutare a mettere in uno stato mentale più funzionale, per quanto riguarda la gestione degli effetti collaterali.

Modifica

Non so perché questo è stato inizialmente sottovalutato; C'è un articolo di John Carmack su Functional Programming in C ++ che inizia come quello che ho detto sopra ( sans la parte di separazione C / Q) - questo è facilmente applicabile anche a Java.

    
risposta data 25.01.2013 - 19:10
fonte
3

Un buon inizio sono i guadi di Neal: il pensiero funzionale.

Dovresti quindi esplorare librerie come: Google guava, sono raccolte per astrazioni essenziali come, funzione, predicato, mappa e operazioni di filtro. (Google per la programmazione funzionale con le raccolte di google, ci sono un paio di buoni blog)

Ci sono un paio di blog su FP in java che ho letto apocalisp.wordpress.com e non me ne sono pentito.

Puoi anche esplorare functionaljava.org per costrutti funzionali più utili come i monoidi.

Imparare Haskell, Scala o Clojure è anche una buona idea, ma ovviamente un po 'più coinvolto.

Buona fortuna!

    
risposta data 25.01.2013 - 12:28
fonte
0

Java 8 introdurrà Lambda che sarà un inizio delicato (o non così delicato per alcuni) per gli sviluppatori di entrare nella programmazione funzionale con Java. Tecnicamente Java ha già alcune funzionalità di programmazione funzionale, ma sono molto goffe (anon inner classes).

    
risposta data 25.01.2013 - 10:30
fonte

Leggi altre domande sui tag