J'ai remarqué récemment que les langages de programmation fonctionnels gagnent en popularité . J'ai récemment vu comment l' indice de Tiobe montre une augmentation de leur popularité par rapport à l'année dernière bien que la plupart d'entre eux n'atteignent même pas les 50 langues les plus populaires selon cet indice.
Et c'est le cas depuis assez longtemps. La programmation fonctionnelle n’est tout simplement pas devenue aussi populaire que d’autres modèles (c.-à-d. La programmation orientée objet).
J'ai toutefois constaté un regain d'intérêt pour le pouvoir de la programmation fonctionnelle et, maintenant que les multicœurs sont de plus en plus populaires, les développeurs ont commencé à s'intéresser à d'autres modèles de concurrence déjà explorés dans le passé par des langages tels que Haskell et Erlang.
Je constate avec un vif intérêt le fait que, malgré leur manque d’acceptation de la part de la communauté, de plus en plus de langues de ce type continuent d’apparaître. Clojure (2007), Scala (2003), F # (2002) ne sont que trois exemples de la dernière décennie.
J'ai moi-même investi du temps à apprendre Haskell et Scala. Et je trouve un grand potentiel dans le paradigme qui était nouveau pour moi alors qu’il était là-bas depuis si longtemps.
Et bien sûr, ma plus grande question est de savoir si l’un d’eux va devenir assez populaire pour qu’il soit envisagé de s’efforcer de le faire, mais c’est une question à laquelle même Mandrake n’a pas pu répondre, malgré tout le bruit que les gens font à leur sujet.
Ce que je veux demander, c'est:
- Dans quels scénarios devrais-je considérer un langage de programmation fonctionnel plus apte à effectuer une tâche donnée? Outre le problème de la programmation parallèle très populaire qui a récemment fait fureur.
- Si je décidais de passer à un langage de programmation fonctionnel, lequel considéreriez-vous comme le plus gros piège auquel je serais confronté? (Outre le changement de paradigme et la difficulté d'évaluer les performances en raison d'une évaluation paresseuse).
- Avec autant de langages de programmation fonctionnels, comment choisir celui qui convient le mieux à vos besoins?
Toute recommandation pour des recherches ultérieures sera plus que bienvenue.
J'ai recherché des opinions sur le Web, et il semble que toute cette popularité renouvelée vienne de l'idée que nous allons bientôt nous retrouver face à la loi de Moore et que les langages de programmation fonctionnels viendront nous sauver héroïquement. Mais si tel est le cas, je dirais qu'il y a plus de probabilités que les langages populaires existants s'adaptent au paradigme.
Certains d’entre vous, ayant peut-être plus d’expérience au quotidien avec ces langues, peuvent offrir plus de perspicacité sur le sujet. Toutes vos opinions seront mieux appréciées et soigneusement examinées.
Merci d'avance!
Réponses:
Tout ce qui implique la création d'une séquence d'éléments de données dérivés à l'aide d'un certain nombre d'étapes de transformation.
Essentiellement, le "problème de tableur". Vous avez des données initiales et un ensemble de calculs ligne par ligne à appliquer à ces données.
Nos applications de production font un certain nombre de résumés statistiques de données; tout cela est mieux abordé fonctionnellement.
Une chose commune que nous faisons est une fusion de trois ensembles de données monstrueux. Semblable à une jointure SQL, mais pas aussi généralisé. Ceci est suivi par un certain nombre de calculs de données dérivées. Ce ne sont que des transformations fonctionnelles.
L'application est écrite en Python, mais dans un style fonctionnel utilisant des fonctions de générateur et des tuples nommés immuables. C'est une composition de fonctions de niveau inférieur.
Voici un exemple concret de composition fonctionnelle.
C'est un des moyens par lesquels la programmation fonctionnelle influence des langages tels que Python.
Parfois, ce genre de chose s’écrit:
Les objets immuables sont le plus difficile des obstacles.
Souvent, vous finissez par calculer des valeurs qui créent de nouveaux objets au lieu de mettre à jour des objets existants. L'idée que c'est un attribut modifiable d'un objet est une habitude mentale difficile à briser.
Une fonction de propriété ou de méthode dérivée est une meilleure approche. Les objets avec état sont une habitude difficile à briser.
Ce n'est pas grave au début. Choisissez n'importe quelle langue à apprendre. Une fois que vous savez quelque chose, vous êtes en mesure d'en choisir un autre pour répondre à vos besoins.
J'ai lu sur Haskell simplement pour comprendre ce qui manque à Python.
la source
"Fonctionnel" est un ensemble de fonctionnalités différentes, dont chacune est utile indépendamment, et je trouve plus utile d'examiner chacune d'elles individuellement.
Immutabilité
Maintenant que je suis au courant, chaque fois que je peux obtenir un résultat immuable, j'essaie toujours de le faire, même dans un programme orienté objet. Il est plus facile de raisonner sur le programme si vous avez des données de type valeur. En règle générale, vous avez besoin de mutabilité pour des éléments tels que les interfaces graphiques et les goulots d'étranglement des performances. Mes entités (utilisant NHibernate) sont également modifiables (ce qui est logique car elles modélisent des données stockées dans une base de données).
Fonctions en tant que types de première classe
Quel que soit votre choix, le fait de contourner les délégués, les actions ou les fonctions est un moyen très pratique de résoudre toute une série de problèmes du monde réel, comme le "modèle au milieu". J'ai également constaté que transmettre un délégué, une action ou une fonction à un objet était plus propre que de laisser cette classe déclarer un événement et de le lier à cet événement (en supposant qu'il n'y ait normalement qu'un seul "écouteur"). Lorsque vous savez qu'il existe un écouteur, l'action de rappel peut être transmise en tant que paramètre constructeur (et être stockée dans un membre immuable!).
Pouvoir composer des fonctions (par exemple, se transformer
Action<T>
en un simpleAction
est également très utile dans certains scénarios.Nous devrions également noter la syntaxe Lambda ici, car vous n’obtenez la syntaxe Lambda que lorsque vous promouvez des fonctions en types de première classe. La syntaxe Lambda peut être très expressive et concise.
Monades
Certes, c’est mon point faible, mais je crois comprendre que les flux de travail de calcul en F #, tels que le
async
flux de travail, sont une monade. C'est une construction subtile mais très puissante. C'est aussi puissant que leyield
mot - clé utilisé pour créer desIEnumerable
classes en C #. Il s’agit essentiellement de construire une machine à états pour vous sous les couvertures, mais votre logique semble linéaire.Évaluation paresseuse et récursivité
Je les ai mises ensemble parce que, même si elles sont toujours regroupées en tant que caractéristiques de la programmation fonctionnelle, elles ont si rapidement pénétré dans des langages autrement impératifs qu'il est difficile de les appeler fonctionnelles.
Expressions S
J'imagine que je ne sais pas trop où mettre ceci, mais la possibilité de traiter le code non compilé comme un objet (et de l'inspecter / le modifier), comme Lisp S-Expressions ou LINQ Expressions, est, à certains égards, l'outil le plus puissant de la programmation fonctionnelle. La plupart des nouvelles interfaces "fluentes" et des DSL .NET utilisent une combinaison de syntaxe lambda et d'expressions LINQ pour créer des API très concises. Sans parler de Linq2Sql / Linq2Nhibernate où votre code C # est "magiquement" exécuté en SQL au lieu de code C #.
C'était la longue réponse à la première partie de votre question ... maintenant ...
Le plus gros écueil auquel j'ai été confronté a été d'essayer de trouver la limite entre l'utilisation de solutions fonctionnelles et les solutions impératives. Cependant, après avoir essayé les deux approches plusieurs fois, vous commencez à vous faire une idée de ce qui fonctionnera mieux.
Si vous connaissez .NET, je vous suggère fortement F #. Par contre, si vous connaissez mieux la machine virtuelle, il y a toujours Clojure . Si vous êtes plus académique que pratique, alors j'opterais pour Common Lisp ou Scheme. Si vous connaissez déjà Python, je pense qu’il existe déjà de nombreuses constructions fonctionnelles.
la source
Cela est vrai si vous comptez les programmes développés par des programmeurs professionnels (ou au moins des personnes se considérant comme telles). Si vous étendez votre réseau pour inclure des programmes développés par des personnes qui ne se considèrent pas comme telles, la PF (ou du moins la programmation dans un style fonctionnel) est assez proche de OO (Excel, Mathematica, Matlab, R ... et même du JavaScript "moderne" ).
Mon opinion personnelle est que le multicœur n’est pas la principale caractéristique de FP (du moins jusqu’à ce que les compilateurs Haskell, Scala, Clojure, F # résolvent le problème de la localisation du cache). La fonction tueur est
map
,filter
,fold
et les amis qui permettent une expression plus succincte d'un grand groupe d'algorithmes. À cela s’ajoute une syntaxe plus concise des langages de PF que les langages homologues les plus courants.En outre, le fait que FP soit plus proche du modèle relationnel réduit le déséquilibre impédance avec le SGBDR ... ce qui est - encore une fois - du moins pour les non-programmeurs - très gentil.
Aussi, lorsque vous avez des difficultés particulières à satisfaire les exigences de "correction" - sous une forme difficile à tester (courante dans le calcul scientifique / l'analyse de données volumineuses, dans le but d'obtenir des résultats auparavant inconnus et en tant que tels, non spécifiables), la PF peut offrir avantages
Combien de vos problèmes peuvent être résolus en sortant déjà des bibliothèques / frameworks sur quelle plate-forme (par exemple, JVM ou .Net), combien sont nouveaux? Existe-t-il des constructions de langage capables d'exprimer ces problèmes directement?
De quel contrôle de bas niveau avez-vous besoin sur les performances d'espace et de temps de votre application?
Quelles sont les exigences de votre "exactitude"?
Pouvez-vous vous permettre de recycler des développeurs et / ou de concurrencer les avantages offerts par certaines niches très rentables du développement de logiciels?
la source
En supposant que vous soyez un développeur C ++ / C # / Java dans l'industrie ...
Soyez prêt pour les pairs grincheux qui ne veulent rien apprendre. Préparez-vous à ce que les patrons aux cheveux pointus imposent de mauvais choix linguistiques "parce qu'ils ont déjà codé". Préparez-vous à ce que les universitaires sur les forums vous encouragent à propos des monoïdes. Préparez-vous à des guerres de langage sans fin, car Scala n’a même pas l’élimination de la queue et Clojure a vraiment besoin de pédales pour tous les supports et ne me lancez pas sur Erlang.
Si vous êtes un programmeur Web, le plus gros piège sera probablement vos cheveux.
Je commencerais par plateforme:
la source
Pour une perspective (certes biaisée) sur cette question, vous pouvez consulter le blog de Bob Harper, Existential Type . Carnegie Mellon a récemment retravaillé son cursus CS pour d'abord enseigner la programmation fonctionnelle, d'autres paradigmes n'étant enseignés qu'une fois que la programmation fonctionnelle est bien ancrée. Harper donne un coup de pouce au fil de la mise en pratique du nouveau curriculum. .
Harper est l’un des principaux développeurs du langage de programmation Standard ML, il est donc juste de dire que sa propre opinion sur la question peut être devinée à l’avance, et il ne craint certainement pas les déclarations controversées dans lesquelles il plaide pour cette position, mais il fait son cas bien.
la source
var
aucune collection mutable ni une seule fois. Ainsi, la pensée impérative est à l’OMI une sorte d’optimisation prématurée qui, comme nous le savons tous, est la racine de tous les maux.Il n'y a pas de formule magique qui vous indique quand utiliser la programmation fonctionnelle. Ce n'est pas comme si la programmation orientée objet était mieux adaptée à nos situations de programmation actuelles. C'est juste une autre façon de structurer les programmes en termes d'un autre ensemble d'abstractions.
La programmation fonctionnelle n'a rien à voir avec la paresse. ML et OCaml sont des langages fonctionnels et stricts. Le plus gros obstacle que vous aurez à surmonter est de structurer les choses en termes de valeurs immuables et de vous garder en tête, quelle que soit l’abstraction utilisée dans le système de types pour les effets secondaires. Les langages fonctionnels conviennent mieux à l'optimisation car ils rendent les effets secondaires très explicites dans le système de types. Haskell utilise des monades, mais il existe d'autres approches pour utiliser des effets dans des langages fonctionnels purs. Nettoyer a des types d'unicité et certains autres langages en développement ont d'autres choses.
Parmi les langages de programmation dont je suis au courant, je dirais que seuls Haskell et Clean peuvent être appelés langages fonctionnels. Tous les autres permettent des effets secondaires sans rendre ces effets explicites dans le système de types. Donc, si vous allez consacrer du temps à l’apprentissage de la programmation fonctionnelle, alors Haskell est probablement le seul qui convient à la facture. Tous les autres que je connais, Erlang, Scala, Clojure, etc., ne fournissent que des abstractions fonctionnelles au-dessus d’un langage impératif. Donc, si vous voulez aborder le paradigme fonctionnel par morceaux, alors je vous recommanderais Scala ou Erlang et si vous voulez tout aborder en même temps et éventuellement abandonner de frustration, alors vous devriez choisir Haskell.
la source
J'attribuerais la hausse actuelle des intérêts dans les langages fonctionnels au fait qu'ils sont idéaux pour l'informatique parallèle. Par exemple, toute l'idée de carte-réduction est basée sur le paradigme fonctionnel. Et il ne fait aucun doute que l'informatique parallèle augmentera, car il est clair qu'actuellement, la montée en gamme est beaucoup plus facile et moins chère que la mise à l'échelle. Même sur le marché grand public, les processeurs ont plus de cœurs, pas plus de GHz.
EDIT: puisque ce n'est pas évident pour tous.
En programmation fonctionnelle pure, une fonction prend une entrée, produit une sortie et n'a aucun effet secondaire. N'ayant aucun effet secondaire, cela signifie qu'il n'a pas d'état partagé, donc pas besoin de mécanismes de synchronisation, qui seraient sinon nécessaires lors de l'exécution simultanée. La synchronisation est la partie la plus difficile de tout logiciel concurrente / parallèle, ce qui la rend purement fonctionnelle, vous n'avez donc pas à vous occuper de la partie la plus difficile du tout.
Comme pour map-reduction, même le nom vient de la programmation fonctionnelle (la cartographie et la réduction sont des opérations typiques du paradigme fonctionnel). Les deux étapes de la réduction de la carte sont des fonctions qui s'exécutent en parallèle, prennent des entrées, produisent des sorties et n'ont aucun effet secondaire. Donc, c'est exactement l'idée de programmation fonctionnelle pure.
Quelques exemples de PF utilisés pour le parallélisme:
la source