Quand utiliser un langage de programmation fonctionnel?

90

Dans quelles situations devrais-je choisir d'utiliser un langage de programmation fonctionnel plutôt qu'un langage orienté objet plus verbeux comme C ++, C # ou Java?

Je comprends ce qu'est la programmation fonctionnelle, ce que je ne comprends pas vraiment, c'est pour quels types de problèmes est-ce une solution parfaite?

Alex Baranosky
la source
Cette question trouve une réponse ici stackoverflow.com/questions/381685/…
krosenvold
2
Toujours. Ou du moins jamais jamais.
Shelby Moore III
1
Avec lambdas, C # est fonctionnel à la limite.
JD

Réponses:

50

Les langages fonctionnels sont, à mon avis, bons pour principalement deux choses: les IA de jeu et les calculs mathématiques. C'est bon dans les IA de jeu en raison de ses jolies manipulations de liste (au moins en Lisp et Scheme), et pour les calculs mathématiques en raison de sa syntaxe. Scheme, Lisp et Haskell ont une syntaxe qui facilite la lecture des calculs mathématiques. La dernière chose que je dois ajouter est que les langages fonctionnels sont des langages vraiment amusants. Mon cours Scheme était l'un des cours avec lesquels je me suis le plus amusé.

martiert
la source
2
Après avoir surmonté le fait que mon cerveau voulait exploser au cours de ma première semaine de cours de compilateur que j'ai suivi dans Scheme, j'ai également trouvé que c'était très amusant (et je me suis beaucoup amélioré dans ce domaine hehe)
Alex Baranosky
1
Quels langages fonctionnels avez-vous utilisés pour les calculs mathématiques?
Jules
8
Aussi, les compilateurs! J'ai entendu des gens qui ont écrit des compilateurs en Haskell dire qu'ils "n'écriront plus jamais un compilateur dans un langage impératif".
ShreevatsaR
1
julesjacobs: J'ai utilisé un peu de haskell et de Scheme pour résoudre des calculs mathématiques simples. Je ne suis pas du tout bon dans ces langues, donc j'ai un chemin à parcourir pour résoudre des problèmes plus complexes. Je ne peux tout simplement pas les rendre assez rapides maintenant.
martiert le
95

J'ai fait moi-même quelques recherches à ce sujet et j'ai pensé que je pourrais ajouter CONCURRENCY à la liste des raisons d'utiliser un langage fonctionnel. Voir à un moment donné dans un proche avenir, la vitesse du processeur ne pourra pas augmenter en utilisant la même technologie de processeur. La physique de l'architecture ne le permettra pas.

C'est donc là qu'intervient le traitement simultané.

Malheureusement, la plupart des langages POO ne peuvent pas tirer parti de plusieurs processeurs à la fois en raison des interdépendances entre les données.

Dans les langages de programmation purement fonctionnels, l'ordinateur peut exécuter deux (ou plusieurs autres) fonctions à la fois car ces fonctions ne modifient pas les informations d'état extérieures.

Voici un excellent article sur la programmation fonctionnelle que vous pourriez apprécier.

Alex Baranosky
la source
38
Je ne dirais pas que la plupart des langages OO ne peuvent pas profiter d'un nombre arbitrairement grand de processeurs. Je dirais que pour qu'un programme tire parti de plusieurs processeurs en même temps de manière efficace et fiable, ce programme doit être organisé de telle sorte que la plupart des unités de code gourmandes en calcul se comportent comme des fonctions pures. Il est possible d'organiser un programme de cette façon dans la plupart des langues. C'est plus facile à faire dans les langages fonctionnels que dans les langages impératifs (y compris orientés objet).
Zak
2
Merci d'avoir lié cet article. Cela m'a vraiment aidé à expliquer les choses.
guptron
13

Un de mes amis a cité l'un de ses professeurs d'université disant quelque chose comme ceci:

Dessinez une grille avec des types de données en haut et des opérations sur ces types de données sur le côté gauche. Si vous coupez la grille verticalement, vous faites OO; si vous coupez la grille horizontalement, vous faites FP.

Ma réponse est que la FP est une approche totalement viable de la programmation avec une gamme d'applications aussi large que l'OO. Comme pour toute discussion sur le choix du langage de programmation, je pense que les questions les plus importantes sont:

  1. Avez-vous le temps d'investir dans l'apprentissage d'une nouvelle notation et d'une nouvelle façon de penser?
  2. Parmi les langages que vous envisagez, lesquels ont des bibliothèques suffisamment riches pour que vous ne réinventiez pas une roue?

En ce qui concerne la première question, si vous faites cela principalement pour la valeur d'apprentissage, je vous suggère de regarder Haskell , en raison du large éventail de supports (livres, articles, communauté active, etc.)

En ce qui concerne la deuxième question, Haskell a une belle gamme de bibliothèques (bien que certaines soient plus matures que d'autres), mais Scala (un langage hybride OO-fonctionnel fonctionnant sur la JVM) présente les avantages que vous pouvez plus progressivement passer au style fonctionnel et vous disposez de la gamme complète des bibliothèques accessibles par Java.

joel.neely
la source
J'ai appris Scheme à l'université, donc je ne veux pas apprendre la programmation fonctionnelle uniquement pour l'expérience. Je préfère apprendre un langage fonctionnel pour des raisons pratiques.
Alex Baranosky
9

Pratiquement tout ce que vous pouvez faire en PP peut être fait en FP, et la même chose en sens inverse. C'est juste une autre façon de coder quelque chose - une autre perspective sur le problème et une manière différente de le résoudre.

Cependant, comme peu de gens utilisent FP, le problème est davantage le manque de bonnes bibliothèques, la portabilité / maintenabilité (puisque le responsable a une meilleure chance de comprendre quelque chose d'écrit en C ++ que Scheme), et le manque de documentation et de communauté. Je sais qu'il existe des documents, cependant, comparez cela à C ++, C # ou Java et vous comprendrez ce que je veux dire.

Cependant, si vous voulez vraiment faire FP, vous pouvez utiliser ce style même en C ++ et C #. Bien sûr, ce ne sera pas un 100% FP si vous utilisez la bibliothèque standard. Malheureusement, je ne pense pas que C # soit optimisé pour être utilisé avec la programmation fonctionnelle et cela créera probablement beaucoup de problèmes de performances.

C'est plus un post subjectif, ce que je pense de la PF. Ce n'est pas une déclaration rigoureuse.

utilisateur35978
la source
8
"Pratiquement tout ce que vous pouvez faire en PP peut être fait en FP" - En fait, c'est exactement tout.
BlueRaja - Danny Pflughoeft
2
@BlueRaja - faites-vous référence à l'exhaustivité de Turing? Si tel est le cas, ce que vous dites ne suit pas. Par exemple, Game of Life de Conway est Turing Complete, mais vous ne pouvez pas l'utiliser pour écrire un pilote de carte vidéo comme vous pouvez le faire en C. De même, je ne vois aucun des derniers jeux écrits en Haskell. Peut faire dans FP! = Pourrait théoriquement faire dans un FP théorique.
Luigi Plinge
@Luigi Plinge Je devrais être d'accord avec BlueRaja. Haskellers discutant de certains pilotes Linux écrits en Haskell. Je n'ai pas de lien mais j'ai aussi entendu dire qu'un OS a été écrit en Haskell (d'autres langages fonctionnels possibles aussi). En ce qui concerne les jeux, je ne vois pas les derniers jeux écrits en C # ou Java, sous-entendez-vous qu'ils ne peuvent pas être utilisés pour de tels jeux? Quoi qu'il en soit, un exemple de jeu en cours d'écriture en FP. Aussi, gardez à l'esprit que la plupart de mes liens sont Haskell, un langage PRAIMENT fonctionnel.
austinprete
@PardonMyRhetoric Vous pouvez évidemment écrire des jeux dans Haskell et faire n'importe quel calcul, mais la vitesse sera plusieurs fois plus lente et l'utilisation de la mémoire plus élevée. Ainsi, un contre-exemple à la déclaration de BlueRaja serait que vous ne pouvez pas écrire "un jeu qui est aussi rapide et utilise autant de mémoire en C" dans FP. C'est un vrai problème pratique, pas un truc pédant (et je ne veux pas du tout critiquer FP - je codifie Scala en ce moment!).
Luigi Plinge
1
@PardonMyRhetoric Il doit également être idiomatique FP. Les benchmarks que vous voyez qui donnent à Haskell des performances approchant celles de C sont écrits dans un style unidiomatique de "bas niveau" que la plupart des programmeurs Haskell ne pouvaient pas écrire. Par exemple, vous pouvez obtenir des performances similaires en créant simplement votre code Haskell et en compilant du code C. Inutile cependant. Une question pratique connexe est de savoir ce que «vous pouvez faire» par rapport à ce que «peut / pourrait être fait». Si quelque chose est trop difficile, peu importe que ce soit possible en théorie (et «possible» pour qui?).
Luigi Plinge
4

Les langages fonctionnels sont bons dans de nombreuses situations. Cela dépend des bibliothèques d'un langage fonctionnel particulier.

Comment répondriez-vous à la question "Quand utiliser un langage de programmation orienté objet?"?

Jules
la source
1
"Quand utiliser un langage de programmation orienté objet?" Lorsque vous voulez modéliser quoi que ce soit par ordinateur, d'un autre côté, j'ai recherché un problème que fp serait la réponse intuitive, je cherche toujours, c'est ainsi que j'ai trouvé cet article.
jimjim
@Arjang Je suppose que la programmation fonctionnelle trouverait une utilité considérable dans les applications de calcul qui n'ont besoin que d'une entrée pour générer une sortie. Pas de mutabilité et pas d'itération
EdgeDev
3

Bien que ce soit une question assez subjective, je voudrais juste ajouter que les langages fonctionnels sont beaucoup utilisés pour analyser les langages spécifiques à un domaine ; la nature fonctionnelle se prête bien à l'analyse des grammaires.

csl
la source
2
Analyser les DSL? Je pensais qu'avec les macros Lisp et autres, les DSL sont implémentées sous forme de macros, pas quelque chose à analyser par les programmes Lisp. YMMV avec des langages non-Lisp. :-P
Chris Jester-Young
1

D'après ce que j'ai vu, c'est plus une question de goût que de fonctionnalité (sans jeu de mots). Il n'y a vraiment rien dans l'un ou l'autre style de langage qui le rend intrinsèquement meilleur ou pire pour des tâches spécifiques.

TED
la source
2
@JonHarrop - Voulez-vous élaborer là-dessus? Je ne trouve pas cela si évident, et ce serait dommage si vous donniez l'impression que vous votiez pour les gens à bas de meer boosterisim.
TED
1
La famille de langages ML a été spécialement conçue pour la métaprogrammation avec l'ajout de fonctionnalités de langage sophistiquées comme la correspondance de motifs pour manipuler les arbres (par exemple les arbres d'expression). Par conséquent, cette famille de langues est intrinsèquement bien meilleure pour cette tâche spécifique.
JD
1
@JonHarrop - Je l'accepterai. Cependant, vous parlez de ML, pas de langages fonctionnels en général. Je suis un fervent partisan du DSL, donc je ne vais certainement pas m'opposer à l'utilisation d'un langage particulier pour la tâche exacte pour laquelle il a été conçu.
TED
Aujourd'hui, la correspondance de motifs se trouve dans presque tous les langages fonctionnels, y compris OCaml, F #, Scala, Haskell, Clojure et Erlang. Par exemple, j'ai récemment construit un moteur de règles métier sur mesure pour un client axé sur les mathématiques. C'est 1000 lignes de F # et est principalement un interprète. Lexing, l'analyse, la vérification de type et l'interprétation des entrées sont beaucoup plus faciles grâce à la correspondance de modèles.
JD
@JonHarrop .. mais pas tous. Ce n'est pas une caractéristique inhérente aux langages fonctionnels, c'est ce que la question posait.
TED
1

En général, utilisez la langue dans laquelle il est le plus facile d'exprimer la solution à un problème. Pour la programmation fonctionnelle, c'est à ce moment que la solution à un problème s'exprime facilement en termes de fonctions , d'où le nom. En général, c'est bon pour les opérations mathématiques, l'IA, la correspondance de modèles; en général tout ce qui peut être décomposé en un ensemble de règles qui doivent être appliquées pour obtenir une réponse. Vous ne pouvez vraiment déterminer le "meilleur" langage à utiliser qu'après avoir suffisamment analysé votre problème. C'est là que le pseudo-code est utile. Si vous vous retrouvez à écrire un pseudo-code qui ressemble à FP, utilisez FP.

Bien sûr, tous les langages de programmation complets sont fonctionnellement équivalents, donc peu importe celui que vous choisissez en termes de problèmes que vous pouvez résoudre. Les principaux effets seront en termes d'efficacité et de précision du codage et de facilité d'entretien.

Notez également qu'il est possible d'imiter FP dans les langages OO grâce à des API intelligemment conçues. Par exemple, j'ai vu de nombreuses bibliothèques Java (JMock en est un exemple) qui utilisent le chaînage de méthodes pour simuler un FP DSL. Ensuite, vous verrez des constructions telles que:

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

Cela crée essentiellement une fonction qui est évaluée pour déterminer si une séquence d'appel sur un objet fictif est correcte. (exemple volé sur http://www.jmock.org/yoga.html )

Une autre syntaxe de type FP dans les langages OO est l'utilisation de fermetures, comme dans Ruby.

Phil
la source
2
"... peu importe celui que vous choisissez en termes de problèmes que vous pouvez résoudre". Seulement si vous disposez d'un temps et d'argent infinis pour résoudre votre problème.
JD