J'ai lu quelques textes sur la programmation déclarative / fonctionnelle (langages), essayé Haskell ainsi que j'en ai é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:
- Programmes apatrides; Pas d'effets secondaires
- Concurrence; Joue extrêmement bien avec la technologie multicœur montante
- Les programmes sont généralement plus courts et dans certains cas plus faciles à lire
La productivité augmente (exemple: Erlang)
La programmation impérative est un très vieux paradigme (pour autant que je sache) et peut-être pas adapté au 21e siècle
Pourquoi les entreprises utilisant ou des programmes écrits dans des langages fonctionnels sont-elles toujours aussi "rares"?
Pourquoi, en examinant les avantages de la programmation fonctionnelle, utilisons-nous toujours des langages de programmation impératifs?
C'était peut-être trop tôt pour ça en 1990, mais aujourd'hui?
functional-programming
pankrax
la source
la source
Réponses:
Parce que tous ces avantages sont aussi des inconvénients.
Les programmes du monde réel concernent tous les effets secondaires et les mutations. Lorsque l'utilisateur appuie sur un bouton, c'est parce qu'il veut que quelque chose se passe. Quand ils tapent quelque chose, ils veulent que cet état remplace tout état qui existait auparavant. Lorsque Jane Smith en comptabilité se marie et change son nom pour Jane Jones, la base de données soutenant le processus commercial qui imprime son chèque de paie a tout intérêt à gérer ce type de mutation. Lorsque vous tirez la mitrailleuse sur l'étranger, la plupart des gens ne modélisent pas mentalement cela comme la construction d'un nouvel étranger avec moins de points de vie; ils modélisent cela comme une mutation des propriétés d'un étranger existant.
Lorsque les concepts du langage de programmation fonctionnent fondamentalement contre le domaine en cours de modélisation, il est difficile de justifier l'utilisation de ce langage.
Le problème est simplement repoussé. Avec des structures de données immuables, vous avez une sécurité de threads bon marché au prix de travailler éventuellement avec des données périmées. Avec les structures de données mutables, vous avez l'avantage de toujours travailler sur de nouvelles données au prix d'avoir à écrire une logique compliquée pour maintenir la cohérence des données. Ce n'est pas comme si l'un d'eux était évidemment meilleur que l'autre.
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 bien 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é doit beaucoup augmenter pour justifier les dépenses massives d'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 zéro, mais maintiennent plutôt des systèmes existants, dont la plupart ont été construits dans des langages non fonctionnels. Imaginez essayer de justifier cela aux actionnaires. Pourquoi avez-vous abandonné votre système de paie actuel pour en construire un nouveau au prix de millions de dollars? "Parce que la programmation fonctionnelle est géniale" ne plaira probablement pas aux actionnaires.
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'adore la programmation fonctionnelle, j'ai rejoint cette équipe parce que je voulais aider à introduire des concepts de la programmation fonctionnelle en C #, et je pense que la programmation dans un style immuable est la voie de l'avenir. Mais il y a des coûts énormes à programmer dans un style fonctionnel qui ne peut pas être simplement ignoré. Le passage à un style plus fonctionnel va se produire lentement et progressivement sur une période de plusieurs décennies. Et c'est ce que ce sera: un virage vers un style plus fonctionnel, pas un embrassement en gros de la pureté et de la beauté de Haskell et 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 compilation. En effet, la programmation fonctionnelle est fondamentalement une bonne adéquation avec le type de problèmes auxquels nous sommes confrontés. Nos problèmes concernent la prise en compte d'informations brutes - chaînes et métadonnées - et leur transformation en différentes chaînes et métadonnées. Dans les situations où des mutations se produisent, comme si quelqu'un tape dans l'EDI, l'espace du problème se prête intrinsèquement à des techniques fonctionnelles telles que la reconstruction incrémentielle uniquement des parties de l'arborescence qui ont changé. De nombreux domaines n'ont pas ces belles propriétés qui les rendent évidemment adaptés à un style fonctionnel .
la source
Les cerveaux de la programmation: conversations avec les créateurs des principaux langages de programmation
la source
La réponse courante est que ni l'un ni l'autre ne remplacera l'autre - ce sont des outils différents qui ont différents ensembles d'avantages et d'inconvénients, et quelle approche a le bord différera en fonction du projet et d'autres problèmes "mineurs" comme la réserve de talents disponible.
Je pense que vous avez raison de dire que la croissance de la concurrence due au multicœur augmentera le pourcentage (de l'ensemble mondial de projets de développement) lorsque la programmation fonctionnelle est choisie par rapport à d'autres styles.
Je pense que c'est rare aujourd'hui parce que la majorité du bassin de talents professionnels d'aujourd'hui est 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 parce qu'il était assez bon, non controversé, et je sais que je ne manquerai jamais de gens qui peuvent le programmer (assez bien).
la source
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 pas à pas 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 une sortie réelle à l'utilisateur pour la consommation), de sorte que le plus pur des langages fonctionnels aura toujours besoin d'un moyen d'entrer dans le monde impératif de temps en temps.
L'état actuel de la technique est que les langages impératifs (tels que C #) empruntent des fonctionnalités au monde fonctionnel (comme les instructions lambda) et vice-versa.
la source
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 pris le relais? Eh bien, c'est le cas. Cela ne ressemble tout simplement pas à Smalltalk. Les langages traditionnels continuent à ressembler davantage à Smalltalk avec C ++, Java, C #, etc. La mode et le style changent plus lentement que tout, donc quand OO est devenu courant, nous l'avons obtenu en collant des parties de OO aux anciennes langues pour qu'il ressemble assez à C à avaler .
Fonctionnel est la même manière. Haskell était un excellent langage fonctionnel. Mais nous avons encore plus de masse de programmeurs traditionnels utilisant la syntaxe de type C aujourd'hui qu'il y a 20 ans. Il doit donc ressembler à C. Terminé: regardez n'importe quelle expression LINQ et dites-moi qu'elle n'est pas fonctionnelle.
la source
dynamic
. C'est la plus petite de ces fonctionnalités, donc je ne suis pas surpris qu'elle ne soit présente que dans la dernière version de la plus moderne de ces trois langues. :-)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 académiques que les autres. 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. Cela n'est vrai que si le lecteur a déjà vu du code impératif, surtout si les exemples précédents font partie de la même "famille" (par exemple, C / C ++, Perl, PHP et Java). Je ne dirais pas que c'est vrai pour n'importe quel langage impératif; prendre une comparaison de Java et Forth, pour faire un exemple extrême.
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 convient de noter que SQL est un langage déclaratif et / ou fonctionnel et jouit d'une énorme popularité.)
Si nous avions été formés au départ sur un langage Lisp-y ou Haskell-y depuis le début, nous penserions tous que les langages de programmation fonctionnels sont parfaitement normaux.
la source
Vous avez déjà obtenu suffisamment de réponses pour que je ne mentionne que quelques éléments que je ne vois pas encore mentionnés.
D'abord et (à mon avis) avant tout, les langages procéduraux ont grandement bénéficié de leur degré de similitude. Pour un exemple, presque tout le monde qui connaît presque toutes les langues classiques de procédure (ou OO) à presque tout degré peut lire la plupart des autres assez bien. J'évite activement de travailler en Java, C #, Cobol, Fortran ou Basic (pour seulement quelques exemples), mais je peux lire n'importe lequel d'entre eux assez bien - presque aussi bien, en fait, que les gens qui les utilisent tous les jours.
Côté fonctionnel, c'est beaucoup moins vrai. Par exemple, je peux également écrire Scheme de façon assez raisonnable, mais cela ne sert à rien en lisant Ocaml ou Haskell (pour seulement quelques exemples). Même au sein d'une même famille (par exemple, Scheme vs., Common Lisp), la familiarité avec l'un ne semble pas se traduire aussi bien par l'autre.
L'affirmation selon laquelle le code fonctionnel est plus lisible a tendance à être vraie uniquement dans une gamme étroite de conditions. Pour les personnes qui connaissent très bien la langue, la lisibilité est en effet excellente - mais pour tout le monde, elle est souvent presque inexistante. Pire, alors que les différences dans les langages procéduraux sont en grande partie de syntaxe et donc relativement faciles à apprendre, les différences dans les langages fonctionnels sont souvent beaucoup plus fondamentales, donc elles nécessitent une étude considérable pour vraiment comprendre (par exemple, savoir que Lisp est de peu d'aide pour comprendre les Monades).
L'autre point majeur est que l'idée que les programmes fonctionnels sont plus courts que les programmes procéduraux est souvent basée davantage sur la syntaxe que sur la sémantique. Les programmes écrits en Haskell (par exemple) sont souvent assez courts, mais leur fonctionnalité n'est qu'une petite partie de cela. Beaucoup si c'est simplement que Haskell a une syntaxe relativement laconique.
Peu de langages purement fonctionnels peuvent bien concurrencer APL pour le code source concis (bien que, pour être honnête, APL prend également en charge la création de fonctions de niveau supérieur, ce n'est donc pas une grande différence comme dans certains autres cas). Au contraire, Ada et C ++ (pour seulement quelques exemples) 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 verbeuse.
la source
Aucun besoin perçu
Je me souviens de la réponse de mon ancien patron Rick Cline quand je lui ai montré une copie de la conférence du prix Turing de John Backus intitulée Can Programming Be Liberated from the von Neumann Style?
Sa réponse: "Peut-être que certains d'entre nous ne veulent pas être libérés du style von Neumann!"
la source
La fonctionnalité est meilleure pour certaines choses et pire pour d'autres, elle ne "prendra donc jamais le dessus". C'est déjà omniprésent dans le monde réel.
Les programmes sans état sont plus faciles à tester. Ceci est aujourd'hui largement apprécié et souvent exploité dans l'industrie.
Vous confondez concurrence et parallélisme.
La concurrence peut être effectuée efficacement en utilisant des 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 car elle est si peu conviviale pour le cache. Les cœurs finissent par lutter pour la mémoire partagée et les programmes parallèles ne se mettent pas à l'échelle.
Scala est souvent considéré comme un langage fonctionnel mais il n'est pas plus fonctionnel que C # qui est l'un des langages les plus populaires au monde aujourd'hui.
La programmation purement fonctionnelle présente de nombreux inconvénients graves, nous utilisons donc des langages fonctionnels impurs comme Lisp, Scheme, SML, OCaml, Scala et C #.
la source
Quand je pense à ce que la programmation fonctionnelle pourrait apporter à mes projets au travail, je suis toujours conduit dans la même direction:
Pour profiter pleinement des 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 brillent pas aussi bien dans un 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 ça ne va pas construire toute la liste et en interne je vais juste avoir une belle boucle qui parcourt les éléments un par un. Cela vous permet d'écrire du code vraiment modulaire. L'interface entre deux modules peut impliquer la remise de structures de données potentiellement vastes, et pourtant vous n'avez pas besoin d'avoir la structure résidente.Mais lorsque vous êtes paresseux, 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 parfois. 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.
la source
Deux choses:
la source