J'ai lu des textes sur la programmation déclarative/fonctionnelle (langages), essayé Haskell et écrit un moi-même. D'après ce que j'ai vu, la programmation fonctionnelle présente plusieurs avantages par rapport au style impératif classique:
La productivité augmente (exemple: Erlang)
La programmation impérative est un très vieux paradigme (à ma connaissance) et ne convient peut-être pas au 21e siècle
Pourquoi les entreprises qui utilisent des programmes écrits dans des langages fonctionnels sont-elles toujours aussi "rares"?
Pourquoi, quand on examine les avantages de la programmation fonctionnelle, utilisons-nous toujours des langages de programmation impératifs?
Peut-être était-il trop tôt pour cela en 1990, mais aujourd'hui?
Parce que tous ces avantages sont aussi des inconvénients.
Programmes sans état; Pas d'effets secondaires
Les programmes du monde réel traitent uniquement des effets secondaires et de la mutation. Lorsque l'utilisateur appuie sur un bouton, c'est qu'il veut que quelque chose se passe. Quand ils tapent quelque chose, ils veulent que cet état remplace celui qui existait auparavant. Lorsque Jane Smith, en comptabilité, se marie et change de nom, elle s'appelle désormais Jane Jones. La base de données relative au processus de gestion qui imprime son chèque de paie doit donc être entièrement consacrée à la gestion de ce type de mutation. Lorsque vous tirez la mitraillette sur l'extraterrestre, la plupart des gens ne modélisent pas cela comme la construction d'un nouvel extraterrestre avec moins de points de vie. ils modélisent cela comme une mutation des propriétés d'un étranger existant.
Lorsque les concepts de langage de programmation vont fondamentalement à l'encontre du domaine modélisé, il est difficile de justifier l'utilisation de ce langage.
La concurrence; Joue extrêmement bien avec la technologie multicœur montante
Le problème est juste poussé. Avec des structures de données immuables, vous bénéficiez d’une sécurité des threads peu coûteuse au détriment du travail avec des données obsolètes. Avec les structures de données modifiables, vous avez l’avantage de toujours travailler sur de nouvelles données au prix de l’écriture d’une logique compliquée pour maintenir la cohérence des données. Ce n'est pas comme si l'un de ceux-ci était évidemment meilleur que l'autre.
Les programmes sont généralement plus courts et, dans certains cas, plus faciles à lire.
Sauf dans les cas où ils sont plus longs et plus difficiles à lire. Apprendre à lire des programmes écrits dans un style fonctionnel est une compétence difficile. les gens semblent beaucoup mieux concevoir les programmes comme une série d’étapes à suivre, comme une recette, plutôt que comme une série de calculs à effectuer.
La productivité augmente (exemple: Erlang)
La productivité doit beaucoup augmenter pour justifier les dépenses énormes liées à l’embauche de programmeurs qui savent programmer dans un style fonctionnel.
Et rappelez-vous, vous ne voulez pas jeter un système qui fonctionne; la plupart des programmeurs ne construisent pas de nouveaux systèmes à partir de rien, mais maintiennent plutôt les systèmes existants, la plupart construits dans des langages non fonctionnels. Imaginez que vous essayez de justifier cela auprès des actionnaires. Pourquoi avez-vous abandonné votre système de paie en place pour en construire un nouveau au coût de millions de dollars? "Parce que la programmation fonctionnelle est géniale" ne devrait pas ravir les actionnaires.
La programmation impérative est un très vieux paradigme (à ma connaissance) et ne convient peut-être pas au 21ème siècle
La programmation fonctionnelle est également très ancienne. Je ne vois pas en quoi l'âge du concept est pertinent.
Ne vous méprenez pas. J'aime la programmation fonctionnelle, j'ai rejoint cette équipe parce que je voulais aider à intégrer les concepts de la programmation fonctionnelle au C #, et je pense qu'une programmation dans un style immuable est la voie de l'avenir. Mais il y a coûts énormes à programmer dans un style fonctionnel qu'on ne peut tout simplement pas oublier. Le passage à un style plus fonctionnel se fera lentement et progressivement sur une période de plusieurs décennies. Et c'est ce que ce sera: un changement vers un style plus fonctionnel, et non pas une approche globale de la pureté et de la beauté de Haskell et de l'abandon du C++.
Je construis des compilateurs pour gagner ma vie et nous adoptons définitivement un style fonctionnel pour la prochaine génération d'outils de compilateur. En effet, la programmation fonctionnelle est fondamentalement adaptée aux problèmes auxquels nous sommes confrontés. Nos problèmes concernent l’acquisition d’informations brutes - chaînes et métadonnées - et leur transformation en chaînes et métadonnées différentes. Dans les situations où des mutations se produisent, comme si quelqu'un tapait dans l'EDI, l'espace du problème se prêtait intrinsèquement aux techniques fonctionnelles telles que la reconstruction incrémentielle des seules parties de l'arbre modifiées. Beaucoup de domaines n'ont pas ces propriétés de Nice, ce qui les rend évidemment sujets à un style fonctionnel.
[Haskell]
Pourquoi pensez-vous qu'aucun langage de programmation fonctionnel n'est entré dans le grand public?
John Hughes: Mauvais marketing! Je ne parle pas de propagande; nous avons eu beaucoup de cela. Je veux dire un choix judicieux d'un créneau de marché cible à dominer, suivi d'un effort déterminé pour faire de la programmation fonctionnelle de loin le moyen le plus efficace de s'attaquer à ce créneau. Aux beaux jours des années 80, nous pensions que la programmation fonctionnelle était bonne pour tout, mais appeler une nouvelle technologie "bon pour tout" revient à l'appeler "particulièrement bon à rien". Quelle est la marque censée être? C'est un problème que John Launchbury a décrit très clairement dans son discours invité à l'ICFP. Galois Connections a failli disparaître sous le nom de "logiciel en langages fonctionnels", mais ils ont pris de l'ampleur depuis qu'ils se sont concentrés sur les "logiciels à haute assurance".
Beaucoup de gens n'ont aucune idée de la manière dont l'innovation technologique se produit et s'attendent à ce qu'une meilleure technologie devienne tout simplement dominante (l'effet "meilleur piège à souris" ), mais le monde ne l'est tout simplement pas.
La réponse courante est que ni l'un ni l'autre ne remplaceront ni ne remplaceront l'autre. Ce sont des outils différents qui présentent des avantages et des inconvénients différents, et quelle approche a-t-elle que Edge changera en fonction du projet et d'autres problèmes "immatériels" tels que le réservoir de talents disponible.
Je pense que vous avez raison de dire que la croissance de la concurrence liée au multicœur augmentera le pourcentage (de l'ensemble des projets de développement) lorsque la programmation fonctionnelle est choisie par rapport à d'autres styles.
Je pense que c'est rare aujourd'hui, car la majorité des professionnels actuels sont les plus à l'aise avec les technologies impératives et orientées objet. Par exemple, j'ai plus d'une fois choisi Java comme langage pour un projet commercial car il était assez bon, non controversé et je sais que je ne manquerai jamais de personnes capables de programmer (assez bien) dedans.
Malgré les avantages de la programmation fonctionnelle, la programmation impérative et orientée objet ne disparaîtra jamais complètement.
La programmation impérative et orientée objet est une description étape par étape du problème et de sa solution. En tant que tel, il peut être plus facile à comprendre. La programmation fonctionnelle peut être un peu obscure.
En fin de compte, un programme utile aura toujours des effets secondaires (comme fournir à l'utilisateur la sortie réelle pour la consommation), de sorte que les langages fonctionnels les plus purs auront encore besoin d'un moyen de pénétrer de temps à autre dans le monde des impératifs.
L'état actuel des choses est que les langages impératifs (tels que C #) empruntent des fonctionnalités du monde fonctionnel (telles que les déclarations lambda) et inversement.
N'est-ce pas?
Smalltalk était un excellent système orienté objet à l'époque. Pourquoi la programmation orientée objet n'a-t-elle pas été prise en charge? Eh bien oui. Cela ne ressemble tout simplement pas à Smalltalk. Les langages traditionnels ont de plus en plus tendance à ressembler à Smalltalk avec C++, Java, C #, etc. La mode et le style changent plus lentement que tout, alors quand OO est devenu courant, nous l’avons obtenu en collant des parties de OO pour les anciennes langues, il ressemblait donc assez à C pour être avalé.
Fonctionnel, c'est pareil. Haskell était un très bon langage fonctionnel. Mais nous avons encore plus de programmeurs grand public utilisant la syntaxe C-like qu’il ya 20 ans. Cela doit donc ressembler à C. Terminé: regardez n'importe quelle expression LINQ et dites-moi qu'elle n'est pas fonctionnelle.
Je crois que les langues impératives sont plus répandues simplement parce que c'est ce à quoi plus de gens sont habitués. Ni la programmation fonctionnelle ni le modèle de programmation impératif ne sont plus obscurs ou plus académiques que l'autre. En fait, ce sont des compléments.
Une affiche a déclaré que le code impératif est plus facile à comprendre que le code de programmation fonctionnel. Ceci n'est vrai que si le lecteur a déjà vu le code impératif, en particulier si les exemples précédents font partie de la même "famille" (par exemple, C/C++, Perl, PHP et Java). Je ne prétends pas que ce soit vrai pour tout langage impératif; comparons Java et Forth, par exemple).
Pour un profane, tous les langages de programmation sont du charabia indéchiffrable, à l'exception peut-être des langages verbeux tels que Hypertalk et SQL. (Il est à noter que SQL est un langage déclaratif et/ou fonctionnel et jouit d'une énorme popularité.)
Si nous avions été initialement formés à un langage LISP-y ou Haskell-y dès le début, nous penserions tous que les langages de programmation fonctionnels sont parfaitement normaux.
Vous avez déjà suffisamment de réponses pour que je ne mentionne que quelques éléments que je ne vois pas encore mentionnés.
Tout d’abord et avant tout (à mon sens), les langages procéduraux ont grandement bénéficié de leur degré de similitude. Par exemple, presque toutes les personnes connaissant presque toutes les langues procédurales classiques (ou OO) à peu près n’importe quel degré peuvent lire assez bien la plupart des autres. J'évite activement de travailler en Java, C #, Cobol, Fortran ou Basic (pour quelques exemples seulement), mais je les lis assez bien - presque aussi bien, en fait, que ceux qui les utilisent tous les jours.
Sur le plan fonctionnel, c'est beaucoup moins vrai. Par exemple, je peux écrire assez raisonnablement Scheme, mais cela ne sert pas à grand-chose à lire Ocaml ou Haskell (pour quelques exemples seulement). Même au sein d’une même famille (Scheme vs., Common LISP), la familiarité avec l’un ne semble pas se traduire aussi bien avec l’autre.
L'affirmation selon laquelle le code fonctionnel est plus lisible n'a tendance à être vraie que dans une plage de conditions étroite. Pour les personnes qui connaissent très bien le langage, la lisibilité est en effet excellente - mais pour tout le monde, elle est souvent quasi inexistante. Pire, bien que les différences de langages procéduraux soient en grande partie de syntaxe et donc relativement faciles à apprendre, les différences de langages fonctionnels sont souvent beaucoup plus fondamentales. Elles nécessitent donc une étude approfondie pour vraiment comprendre (par exemple, savoir que LISP n’aide pas beaucoup à comprendre les monades).
L’autre point important est que l’idée que les programmes fonctionnels sont plus courts que les programmes procéduraux est souvent davantage basée sur la syntaxe que sur la sémantique. Les programmes écrits en Haskell (par exemple) sont souvent assez courts, mais sa fonctionnalité n’est qu’une petite partie de cela. Beaucoup si c'est simplement que Haskell a une syntaxe relativement concise.
Peu de langages purement fonctionnels peuvent concurrencer APL pour un code source concis (bien que, par souci d'équité, APL prenne également en charge la création de fonctions de niveau supérieur, la différence n'est donc pas très grande, comme dans d'autres cas). Au contraire, Ada et C++ (pour quelques exemples seulement) peuvent être assez compétitifs en termes de nombre d'opérations nécessaires pour accomplir une tâche donnée, mais la syntaxe est (au moins généralement) sensiblement plus verbeux.
Pas de besoin perçu
Je me souviens de la réponse de mon ancien patron Rick Cline lorsque je lui ai montré une copie de la conférence de John Backus intitulée Turing Award intitulée La programmation peut-elle être libérée du style von Neumann?
Sa réponse: "Peut-être que certains d'entre nous ne ne veulent pas être libérés du style de von Neumann!"
Pourquoi la programmation fonctionnelle n'est-elle pas encore prise en charge?
Fonctionnel étant meilleur pour certaines choses et pire pour d'autres, il ne "prendra jamais le dessus". Cependant, il est déjà omniprésent dans le monde réel.
Programmes sans état; Pas d'effets secondaires
Les programmes sans état sont plus faciles à tester. Ceci est maintenant largement apprécié et souvent exploité dans l'industrie.
La concurrence; Joue extrêmement bien avec la technologie multicœur croissante Les programmes sont généralement plus courts et, dans certains cas, plus faciles à lire La productivité augmente (exemple: Erlang)
Vous associez concurrence et parallélisme.
La simultanéité peut être réalisée efficacement à l'aide de processus séquentiels communicants (CSP). Le code à l'intérieur d'un CSP peut muter son état local, mais les messages envoyés entre eux doivent toujours être immuables.
La programmation purement fonctionnelle joue extrêmement mal avec le multicœur parce que le cache est hostile. Les cœurs finissent par se disputer la mémoire partagée et les programmes parallèles ne sont pas évolutifs.
Pourquoi les entreprises utilisant des programmes écrits dans des langages fonctionnels sont-elles encore si "rares"?
La scala est souvent considérée comme un langage fonctionnel, mais elle n’est pas plus fonctionnelle que le c #, qui est l’un des langages les plus populaires au monde.
Pourquoi, quand on examine les avantages de la programmation fonctionnelle, utilisons-nous toujours des langages de programmation impératifs?
La programmation purement fonctionnelle présente de nombreux inconvénients sérieux. Nous utilisons donc des langages fonctionnels impurs tels que LISP, Scheme, SML, OCaml, Scala et C #.
Quand je réfléchis à ce que la programmation fonctionnelle pourrait apporter à mes projets au travail, je suis toujours dirigée dans la même direction:
Pour obtenir tous les avantages de la programmation fonctionnelle, vous avez besoin de paresse. Oui, il existe des langages fonctionnels stricts, mais les avantages réels de la programmation fonctionnelle ne ressortent pas aussi bien dans le code strict. Par exemple, dans Haskell, il est facile de créer une séquence d'opérations paresseuses sur une liste, de les concaténer et de les appliquer à une liste. Par exemple. op1 $ op2 $ op3 $ op4 $ someList
. Je sais que cela ne va pas construire la liste complète et en interne, je vais juste avoir une boucle de Nice qui parcourt les éléments un à la fois. Cela vous permet d'écrire du code vraiment modulaire. L'interface entre deux modules peut impliquer le transfert de structures de données potentiellement vastes, sans pour autant que la structure soit résidente.
Mais lorsque vous avez la paresse, il devient difficile de raisonner sur l'utilisation de la mémoire. La modification des indicateurs du compilateur Haskell modifie fréquemment la quantité de mémoire utilisée par un algorithme de O(N) à O (1), sauf que parfois ce n'est pas le cas. Ce n'est pas vraiment acceptable lorsque vous avez des applications qui doivent utiliser au maximum toute la mémoire disponible, et ce n'est pas génial même pour les applications qui n'ont pas besoin de toute la mémoire.
Deux choses: