La programmazione funzionale è possibile in Java? [chiuso]


42

Stavo navigando nel Bookstore di Amazon.com e mi sono imbattuto nel libro "Programmazione funzionale per sviluppatori Java" .

Conosco una programmazione funzionale di base e ho programmato in Java per 3 anni.

Vorrei sapere se la programmazione funzionale è possibile anche in Java?


2
Lo stile è possibile ma la sua verbosità potrebbe essere troppo da sopportare data la sintassi di Java: funzionalejava.org
Yuriy Zubarev

7
@nCdy Perché controllare JRuby? si prega di fornire ulteriori spiegazioni.
Chirone,

1
check groovy :-)
Ant

6
Penso che questo sia il tipo di domanda che solleva la distinzione tra Java-the-language e Java-the-platform.
Thomas Owens

2
@ ThorbjørnRavnAndersen: Cosa ti fa pensare che la "programmazione funzionale" sia definita da "valutazione pigra"? Sembra uno strano esempio da scegliere ...
John Bartholomew

Risposte:


70

Dipende da cosa intendi per "programmazione funzionale" e per "possibile".

Ovviamente puoi implementare le cose seguendo un paradigma funzionale. Tuttavia, il linguaggio Java non fornisce lo zucchero sintattico, quindi alcune cose saranno noiose nella migliore delle ipotesi, e altre saranno estremamente arcane.

Allo stesso modo, puoi benissimo scrivere codice orientato agli oggetti in un linguaggio riconosciuto come non-OO, come C.

Librerie Java

Ci sono librerie che possono aiutarti a farlo, facendo già il lavoro per te e nascondendo le cose arcane:

Ciò ti consentirà di scrivere codice Java con un approccio più funzionale e una sintassi e una semantica forse più familiari, come ti aspetteresti da un linguaggio FP-competente. Entro limiti ragionevoli, cioè.

JVM Languages

E ovviamente, puoi implementare un linguaggio funzionale su Java. In modo che tu possa usarlo come linguaggio FP. Il che è un po 'più alto di astrazione rispetto a quello che hai chiesto, ma relativamente nel contesto (anche se sto tradendo un po' qui, scontato).

Ad esempio, controlla:

Lingue JVM più o meno funzionali

Anche se potrebbero non essere esattamente quello che vuoi, ci sono un certo numero di altre lingue che sono state portate sulla piattaforma Java e che potrebbero liberarti dalla natura relativamente non orientata al divertimento di Java (sì, gioco di parole) e già darti di più flessibilità. Notevoli contendenti come JRuby , Jython e Rhino (rispettivamente per Ruby , Python e JavaScript / ECMAScript ) offrono anche un potenziale interessante per la programmazione funzionale, sebbene probabilmente non siano realmente linguaggi di programmazione funzionali per natura. Kotlin di JetBrains, pur riconoscendo chiaramente che non è un linguaggio funzionale, supporta alcuni costrutti funzionali e vale anche la pena dare un'occhiata.

Ulteriori letture

Potresti anche voler leggere o guardare questi articoli o video:


2
Il codice sorgente di Clojure è ora ospitato su Github github.com/clojure/clojure
Chiron

@La leggenda del 1982: sono stato più veloce del tuo commento, ho già cambiato il link al sito clojure.org ufficiale :) Ma grazie per averlo catturato così in fretta! È bello vedere le persone reagire rapidamente.
haylem,

C'è anche ABCL ( common-lisp.net/project/armedbear ), ma non ho idea di dove rientri nella scala matura / non matura ed è un'implementazione di Lisp comune.
Vatine,

@Vatine: interessante, non ne avevo mai sentito parlare. Avrà una rapida occhiata e lo aggiungerà.
Hayylem

1
Adoro il termine "Turing Tarpit" di Alan Perlis per aver tentato di fare qualcosa che un languge può fare (perché è diventato turing completo) ma solo con tale dolore e complessità che non dovrebbe essere tentato.
itsbruce,

11

Sto leggendo il libro che hai citato. È davvero buono BTW.

Sì, è possibile essere funzionali in Java. Non so fino a che punto puoi raggiungerlo, ma puoi implementare molti modi di dire funzionali di programmazione.

Una delle cose più importanti è cercare di codificare con la mentalità "Non mutare gli stati".

Ad esempio, usi la parola chiave finale per ottenere l'immutabilità. Se si intende utilizzare una struttura di dati, è necessario codificare in strutture di dati immutabili. La libreria di Google Guava lo sta già facendo.

Anche per la programmazione concorrente, puoi fare affidamento sul framework Akka (il modello dell'attore).

Vale la pena ricordare che il bytecode JVM non supporta (almeno ancora) l'ottimizzazione della coda, una caratteristica molto importante per i linguaggi di programmazione funzionale.


"Vale la pena ricordare che il bytecode JVM non supporta (almeno ancora) l'ottimizzazione delle chiamate di coda, una caratteristica molto importante per i linguaggi di programmazione funzionale.": Cosa intendi? Scala ha TCO.
Giorgio,

@Giorgio: Scala fa TCO al momento della compilazione.
scrwtp

@scrwtp: c'è una penalità per questo? O quali sono gli svantaggi del TCO in fase di compilazione?
Giorgio,

@Giorgio: Quello che intendevo dire è che il bytecode java non lo supporta nativamente, proprio come Chiron aveva inizialmente affermato. I linguaggi funzionali si aggirano attorno ad esso, compilando le chiamate ricorsive della coda in loop, ma è una caratteristica del compilatore language-> bytecode, non della JVM.
scrwtp

@scrwtp: la risposta di Chiron afferma "Vale la pena ricordare che il bytecode JVM non supporta (almeno ancora) l'ottimizzazione della coda, una caratteristica molto importante per i linguaggi di programmazione funzionale". farlo sembrare un'implementazione di un linguaggio funzionale sulla JVM è penalizzato ma (e sembriamo concordare su questo) ciò non è vero poiché l'ottimizzazione delle chiamate di coda può essere simulata nel codice compilato. Quindi sono d'accordo con l'affermazione di Chirone, ma la trovo un po 'fuorviante.
Giorgio,

6

Sì, è sicuramente possibile , allo stesso modo in cui è possibile in qualsiasi combinazione di linguaggio / ambiente di esecuzione completa. Puoi persino farlo funzionare abbastanza bene se sai cosa stai facendo.

Non sono sicuro di quanto sia sensato. In particolare, tieni presente che non è particolarmente idiomatico (cioè sembrerà molto strano, dovrai fare alcune cose non convenzionali e confondere le persone che sono abituate a Java normale)

Ti ritroverai con un codice dall'aspetto strano, ad esempio per definire una nuova funzione:

Function twoStrings=new Function() {
  public Object apply(Object param1) {
    // do something to param1 and return a result
  }
}

Per eseguire la programmazione funzionale in genere è necessario:

  • Funzioni di prima classe - facili da creare in Java definendo una classe o un'interfaccia astratta che rappresenta la tua "Funzione" e ha un metodo "applica" che applica la funzione a uno o più parametri.
  • Chiusure : crea un'istanza dell'oggetto funzione sopra con i valori chiusi memorizzati nei campi finali. Per questo puoi usare una classe interna anonima.
  • Una libreria di funzioni standard di ordine superiore - questo è più complicato, tuttavia puoi comunque scriverne uno tuo per avviare un linguaggio funzionale semplice in poche ore. Se vuoi qualcosa di più elaborato, puoi controllare altre librerie funzionali che le persone hanno creato in Java.

Quindi è possibile come esercizio e persino un interessante progetto hobby. Ma vuoi davvero fare una seria programmazione funzionale mantenendo i vantaggi della JVM / accedere alle librerie Java, quindi Clojure è di gran lunga la tua migliore opzione secondo me.

ps poiché il nucleo di Clojure è in realtà scritto in Java, in realtà è un esempio molto interessante di come eseguire la programmazione funzionale in Java nascondendo i dettagli disordinati dietro una bella nuova sintassi del linguaggio moderno. Il codice sorgente di Clojure è su GitHub per chi è interessato.


È interessante notare che ho notato che l'ultima versione di IntelliJ IDEA piegherà queste tute anonime in una forma più compatta per la visualizzazione nell'editor. Fa un buon lavoro dignitoso nel nascondere l'innesto ridondante. Ovviamente tutto ciò sarà irrilevante come viene Java 8.
Ben Hardy,

4

È possibile essere in qualche modo funzionale in Java. Farlo è davvero doloroso . Invece di

myList.each { doSomething(it); }

Hai qualcosa del tipo:

myList.each(new Function() { public void do(Object arg) { something(); }})

E se vuoi una vera programmazione funzionale, con chiusure e funzioni come oggetti di prima classe, scegli un'altra lingua. Scala, Clojure, Groovy funzionano tutti sulla JVM e possono interagire con le classi Java legacy. .


La programmazione funzionale non riguarda l'uso di blocchi invece di classi anonime. Java 8 avrà blocchi, quindi il tuo codice pubblicato apparirà più elegante ma non sarà una programmazione funzionale.
Chirone,

@Legend: lo capisco, ma evidentemente non lo ha spiegato bene.
Kevin Cline il

questo è svista / svista. con qualsiasi lingua, devi effettivamente definire la funzione QUALCUNO, non puoi saltare quella parte. Quindi Java è quasi altrettanto conciso, tutto ciò che devi fare è rendere un oggetto anonimo. Puoi farlo: Function f = new Function () {public void do () {}}; .... quindi ... chiama quella funzione .... myMethodToCallAFunction (Funzione f) {f.do ()} ... ecco, bros e brolinis. affrontarla.
Alexander Mills,

3

La risposta è un clamoroso "sì, certo", ma secondo me una delle caratteristiche più importanti in molti linguaggi funzionali è l'eccellente sistema di tipi. Non sarai mai in grado di gestirlo da solo in Java.

Se vuoi scrivere programmi funzionali e tuttavia rimanere con la JVM, posso consigliare ai soliti sospetti Scala e Clojure di guardare Frege . Frege ha una sintassi e un sistema di tipi molto vicini a Haskell, ma i programmi vengono tradotti direttamente in codice Java e possono interagire con altri codici Java.


2

Bene, tutto è possibile. È possibile eseguire una programmazione orientata agli oggetti in C; non è una buona idea.

Java non è stato progettato per FP, quindi se stai provando a fare tutto in uno stile puramente FP, avrai problemi. Combatterai la lingua, invece di lavorare con essa. E non solo la lingua: ci sono anche tutte le meravigliose librerie Java gratuite. Quindi non andare per FP puro; prendi alcune delle idee alla base di FP e integrale nel tuo codice Java, ma capisci che non puoi farlo con tutte le idee.


0

Sei incoraggiato dal team OpenJDK a scaricare i loro ultimi binari OpenJDK 8 e giocare con le nuove espressioni lambda e i nuovi modi di dire funzionali introdotti nell'API Collections (tra gli altri). Puoi programmare in un chiaro stile funzionale. Vedi "Programmazione funzionale in Java?" per un confronto delle raccolte JDK8 con librerie pre Java8 come Guava, FunctionalJava e LambdaJ.


-3

Può sembrare possibile ma non sarà una pura programmazione funzionale. Ciò può comportare una programmazione imperativa.

Non si può chiedere perché si riferisca a una possibile programmazione funzionale, come menzionato da Haylem. Ecco qui:

Dipende da cosa intendi per "programmazione funzionale" e per "possibile".

La programmazione funzionale non può avere definizioni o significati diversi sebbene possa avere molte spiegazioni.
Come OOP, possiamo chiedere "cosa intendi con OOP?".
Sicuramente ci saranno molte spiegazioni ma riguarderà solo un obiettivo, l'obiettivo di OOP.
Lo stesso vale per la programmazione funzionale .

Quando diciamo significato funzionale i programmi consistono in funzioni.
Il ruolo delle funzioni è di restituire un argomento / parametro valutato (l'argomento è variabile se l'espressione è arrivata quando si chiama la funzione mentre il parametro è variabile che fa parte della dichiarazione della funzione).

Inoltre, le funzioni restituiranno sempre lo stesso risultato quando vengono passati gli stessi argomenti. In questo modo è più facile evitare bug o eseguire il debug di bug futuri. Con la programmazione funzionale possiamo evitare effetti collaterali come la modifica della variabile globale.

esempio in JavaScript:

function increment(lis){
    return lis.map(
        function (x){
            return x+2;
        }
    );
}

var myList = [4, 7, 2, 3];
console.log(increment(myList));
console.log(myList);

L'incremento della funzione aggiunge 1 valore a ciascuno degli elementi all'interno dell'oggetto e restituisce il risultato. Il valore di myList non è cambiato ma quando abbiamo chiamato le funzioni abbiamo visto il valore aggiunto agli elementi di quell'oggetto.

Come la mia risposta a Is programmazione funzionale possibile in Java? , Credo che non sia possibile avere una vera programmazione funzionale in Java. Perché java è davvero progettato per essere OOP in cui estende la programmazione imperativa e la migliora per mantenibilità. Quando lo stato di un oggetto, una variabile, ecc., È cambiato, questa è già una programmazione imperativa.

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.