La programmation fonctionnelle est-elle possible en Java? [fermé]

42

Je parcourais la librairie Amazon.com et je suis tombé sur le livre "Programmation fonctionnelle pour les développeurs Java" .

Je connais une programmation fonctionnelle très basique et je programme en Java depuis 3 ans.

J'aimerais savoir si la programmation fonctionnelle est même possible en Java?

Vinoth Kumar CM
la source
2
Le style est possible mais sa verbosité pourrait être trop difficile à supporter compte tenu de la syntaxe de Java: functionaljava.org
Yuriy Zubarev
7
@ nCdy Pourquoi vérifier JRuby? veuillez fournir plus d'explications.
Chiron
1
Vérifiez groovy :-)
Ant's
6
Je pense que c'est le genre de question qui soulève la distinction entre Java-le-langage et Java-la-plate-forme.
Thomas Owens
2
@ ThorbjørnRavnAndersen: Qu'est-ce qui vous fait penser que la "programmation fonctionnelle" est définie par "l'évaluation paresseuse"? Cela semble un exemple étrange à choisir ...
John Bartholomew Le

Réponses:

70

Cela dépend de ce que vous entendez par "programmation fonctionnelle" et par "possible".

Vous pouvez évidemment mettre en œuvre des choses suivant un paradigme fonctionnel. Cependant, le langage Java ne fournit pas le sucre syntaxique pour cela, de sorte que certaines choses seront fastidieuses au mieux, et que d'autres seront extrêmement obscures.

De même, vous pouvez très bien écrire du code orienté objet dans un langage reconnu comme étant non-OO, comme C.

Bibliothèques Java

Il existe des bibliothèques qui peuvent vous aider à le faire, en faisant déjà le travail pour vous et en cachant les choses obscures:

Celles-ci vous permettront d’écrire du code Java avec une approche plus fonctionnelle et éventuellement une syntaxe et une sémantique plus familières, comme vous le voudriez d’un langage compétent en FP. Dans la raison, c'est.

Langues JVM

Et évidemment, vous pouvez implémenter un langage fonctionnel au-dessus de Java. Pour que vous puissiez ensuite utiliser celui-ci comme langue de PF. Ce qui est un peu un niveau d'abstraction plus élevé que ce que vous avez demandé, mais relativement dans le contexte (bien que je triche un peu ici, d'accord).

Par exemple, consultez:

Langages JVM fonctionnels plus ou moins fonctionnels

Même s’ils ne sont peut-être pas exactement ce que vous voulez, il existe un certain nombre de langages qui ont été portés sur la plate-forme Java et qui pourraient vous libérer de la nature relativement peu amusante de Java (oui, le jeu de mots) et vous en donner déjà plus. souplesse. Des concurrents notables comme JRuby , Jython et Rhino (respectivement pour Ruby , Python et JavaScript / ECMAScript ) offrent également un potentiel intéressant pour la programmation fonctionnelle, même s’ils ne sont pas vraiment des langages de programmation fonctionnels par nature. Kotlin de JetBrains, tout en reconnaissant clairement que ce n'est pas un langage fonctionnel, supporte certaines constructions fonctionnelles et mérite également un coup d'oeil.

Lectures complémentaires

Vous voudrez peut-être aussi lire ou regarder ces articles ou vidéos:

poudre de foin
la source
2
Le code source de Clojure est maintenant hébergé sur Github github.com/clojure/clojure
Chiron
@The Legend of 1982: J'étais plus rapide que votre commentaire, j'avais déjà changé le lien vers le site officiel de clojure.org :) Mais merci de l'avoir capturé si rapidement! C'est bien de voir les gens réagir rapidement.
Hayem
Il y a aussi ABCL ( common-lisp.net/project/armedbear ), mais je ne sais pas du tout où il se situe sur l'échelle mature / non mature et il s'agit d'une implémentation Common Lisp.
Vatine
@Vatine: intéressant, je n'en avais absolument jamais entendu parler. Va jeter un coup d'oeil et l'ajouter.
haylem
1
J'aime le terme "Turing Tarpit" d'Alan Perlis pour avoir tenté de faire quelque chose qu'une langue peut faire (parce qu'elle est complète), mais seulement avec une douleur et une complexité telles qu'elle ne devrait pas être tentée.
Itsbruce
11

Je lis le livre que vous avez mentionné. C'est vraiment bon BTW.

Oui, il est possible d'être fonctionnel en Java. Je ne sais pas dans quelle mesure vous pouvez y arriver, mais vous pouvez implémenter de nombreux idiomes de programmation fonctionnels.

L’une des choses les plus importantes est d’essayer de coder avec la mentalité «Ne pas muter d’états».

Par exemple, vous utilisez le mot-clé final pour obtenir l'immutabilité. Si vous souhaitez utiliser une structure de données, vous devez coder dans des structures de données immuables. La bibliothèque Google Guava le fait déjà.

Également pour la programmation simultanée, vous pouvez compter sur le cadre Akka (le modèle d'acteur).

Il est à noter que le bytecode de la machine virtuelle Java ne prend pas en charge (du moins pour le moment) l’optimisation d’appel en queue, une fonctionnalité très importante pour les langages de programmation fonctionnels.

Chiron
la source
"Il est à noter que le bytecode de la machine virtuelle Java ne supporte pas (du moins pour le moment) l'optimisation des appels en attente, une fonctionnalité très importante pour les langages de programmation fonctionnels.": Que voulez-vous dire? Scala a un coût total de possession.
Giorgio
@Giorgio: Scala fait le TCO au moment de la compilation.
Scrwtp
@scrwtp: Y a-t-il une pénalité de performance à cause de cela? Ou quels sont les inconvénients du coût total de possession au moment de la compilation?
Giorgio
@Giorgio: Ce que je voulais dire, c'est que le bytecode java ne le supporte pas nativement, tout comme Chiron l'avait déclaré à l'origine. Les langages fonctionnels fonctionnent autour de cela, compilant des appels finement récursifs en boucles, mais c'est une fonctionnalité du compilateur language-> bytecode, pas de la machine virtuelle Java.
scrwtp
@scrwtp: La réponse de Chiron indique "Il est intéressant de noter que le bytecode de la machine virtuelle Java ne prend pas en charge (du moins pour le moment) l'optimisation d'appel en attente, une fonctionnalité très importante pour les langages de programmation fonctionnels." faire croire que l'implémentation d'un langage fonctionnel sur la machine virtuelle est pénalisé mais (et nous semblons être d'accord sur ce point), ce n'est pas vrai, car l'optimisation des appels en aval peut être simulée dans le code compilé. Je suis donc d'accord avec la déclaration de Chiron mais je la trouve un peu trompeuse.
Giorgio
6

Oui, c'est tout à fait possible , de la même manière que dans n'importe quelle combinaison langage / environnement d'exécution complet. Vous pouvez même obtenir de bons résultats si vous savez ce que vous faites.

Je ne sais pas à quel point c'est raisonnable. Sachez en particulier qu’il n’est pas particulièrement idiomatique (c’est-à-dire que cela aura l’air très étrange, vous devrez faire des choses non conventionnelles et dérouter des gens habitués à Java habituel)

Vous allez vous retrouver avec un code étrange, par exemple pour définir une nouvelle fonction:

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

Pour faire de la programmation fonctionnelle, vous avez généralement besoin de:

  • Fonctions de première classe - faciles à créer en Java en définissant une classe abstraite ou une interface représentant votre "Fonction" et disposant d'une méthode "apply" appliquant la fonction à un ou plusieurs paramètres.
  • Fermetures - créez une instance de votre objet fonction ci-dessus avec les valeurs fermées stockées dans les champs finaux. Vous pouvez utiliser une classe interne anonyme pour cela.
  • Une bibliothèque de fonctions standard d’ordre supérieur - c’est plus compliqué, mais vous pouvez toujours écrire les vôtres pour amorcer un langage fonctionnel simple en quelques heures. Si vous voulez quelque chose de plus sophistiqué, vous pouvez consulter les autres bibliothèques fonctionnelles que les gens ont construites en Java.

C'est donc possible comme exercice et même comme projet de loisir intéressant. Mais vous voulez vraiment faire de la programmation fonctionnelle sérieuse tout en conservant les avantages de la JVM / accès aux bibliothèques Java, alors Clojure est de loin votre meilleure option à mon avis.

ps étant donné que le noyau de Clojure est écrit en Java, il s’agit en fait d’un exemple de cas très intéressant illustrant la programmation fonctionnelle en Java, tout en masquant les détails compliqués d’une belle nouvelle syntaxe de langage moderne. Le code source de Clojure est sur GitHub pour les personnes intéressées.

Mikera
la source
Il est intéressant de noter que j'ai remarqué que la dernière version d'IntelliJ IDEA pliera ces onesies anonymes en une forme plus compacte à afficher dans l'éditeur. Fait-il un travail décent de cacher le travail cruel redondant. Bien sûr, tout cela sera sans importance avec Java 8.
Ben Hardy
4

Il est possible d'être quelque peu fonctionnel en Java. Cela est très douloureux . Au lieu de

myList.each { doSomething(it); }

Vous avez quelque chose comme:

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

Et si vous voulez une vraie programmation fonctionnelle, avec des fermetures et des fonctions comme objets de première classe, choisissez un autre langage. Scala, Clojure, Groovy s’exécutent tous sur la machine virtuelle Java et peuvent interagir avec les classes Java héritées. .

Kevin Cline
la source
La programmation fonctionnelle ne consiste pas à utiliser des blocs au lieu de classes anonymes. Java 8 va avoir des blocs, donc votre code posté sera plus élégant mais ce ne sera pas une programmation fonctionnelle.
Chiron
@ Legend: Je comprends cela, mais évidemment, je ne l'ai pas bien expliqué.
kevin cline
c'est de la surveillance / de la sous-surveillance. quelle que soit la langue, vous devez définir la fonction PARTOUT, vous ne pouvez pas ignorer cette partie. Donc, Java est presque aussi concis, il suffit de rendre l’objet Function non anonyme. Vous pouvez faire ceci: Function f = new Function () {public void do () {}}; .... alors ... appelez cette fonction .... myMethodToCallAFunction (Fonction f) {f.do ()} ... c'est tout, bros et brolinis. Faites avec.
Alexander Mills
3

La réponse est un "oui, bien sûr" retentissant, mais à mon avis, l'une des caractéristiques les plus importantes de nombreux langages fonctionnels est l'excellent système de types. Vous ne pourrez jamais gérer cela vous-même en Java.

Si vous souhaitez écrire des programmes fonctionnels tout en restant dans la machine virtuelle, je peux vous recommander, parmi les suspects habituels, Scala et Clojure, d’examiner Frege . Frege a une syntaxe et un système de types très proches de Haskell, mais les programmes sont traduits directement en code java et peuvent interagir avec d'autres codes java.

Ingo
la source
2

Eh bien, toutes sortes de choses sont possibles. Il est possible de faire de la programmation orientée objet en C; ce n'est tout simplement pas une très bonne idée.

Java n'a pas été conçu pour la FP, donc si vous essayez de tout faire dans un style purement FP, vous aurez des problèmes. Vous allez combattre la langue, au lieu de travailler avec elle. Et pas seulement la langue - il y a aussi toutes les merveilleuses bibliothèques Java gratuites. Alors n'allez pas pour la pure FP; Prenez quelques-unes des idées derrière FP et intégrez-les dans votre code Java, mais comprenez que vous ne pouvez pas le faire pour toutes les idées.

Mike Baranczak
la source
0

L’équipe OpenJDK vous encourage à télécharger les derniers fichiers binaires OpenJDK 8 et à vous amuser avec les nouvelles expressions lambda et les nouveaux idiomes fonctionnels introduits dans l’API Collections (entre autres). Vous pouvez programmer dans un style fonctionnel clair. Voir "Programmation fonctionnelle en Java?" pour une comparaison de collections JDK8 avec des bibliothèques antérieures à Java8 telles que Guava, FunctionalJava et LambdaJ.

JohanN
la source
-3

Cela peut sembler possible, mais ce ne sera pas une programmation purement fonctionnelle. Cela peut entraîner une programmation impérative.

Il n’ya pas à se demander pourquoi il entend par possible programmation fonctionnelle, comme le mentionne haylem. C'est ici:

Cela dépend de ce que vous entendez par "programmation fonctionnelle" et par "possible".

La programmation fonctionnelle ne peut pas avoir une définition ou un sens différent, bien qu’elle puisse avoir de nombreuses explications.
Comme la programmation orientée objet, pouvons-nous demander "qu'entendez-vous par la programmation orientée objet?".
Il y aura certainement beaucoup d'explications, mais cela ne concernera qu'un seul objectif, l'objectif de la programmation orientée objet.
La même chose s'applique à la programmation fonctionnelle .

Lorsque nous parlons de signification fonctionnelle, les programmes sont constitués de fonctions.
Le rôle des fonctions est de renvoyer un argument / paramètre évalué (argument est variable est l'expression utilisée lors de l'appel de la fonction alors que paramètre est une variable qui fait partie de la déclaration de fonction).

De plus, les fonctions renverront toujours le même résultat lorsque les mêmes arguments sont passés. De cette façon, il est plus facile d’éviter les bugs ou de déboguer les futurs bugs. Grâce à la programmation fonctionnelle, nous pouvons éviter les effets secondaires tels que la modification de la variable globale.

exemple en 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'incrément de fonction ajoute 1 valeur à chacun des éléments à l'intérieur de l'objet et renvoie le résultat. La valeur de myList n'a pas changé, mais lorsque nous avons appelé les fonctions, nous avons constaté la valeur ajoutée des éléments de cet objet.

En réponse à La programmation fonctionnelle est-elle possible en Java? , Je crois qu’il n’est pas possible d’avoir une vraie programmation fonctionnelle en Java. Parce que java est vraiment conçu pour être une POO dans laquelle il étend la programmation impérative et l’améliore pour la maintenabilité. Lorsque l'état d'un objet, d'une variable, etc. a changé, la programmation est déjà impérative.

L34Rn3R
la source