J'ai toujours pensé que la programmation fonctionnelle pouvait être réalisée en Python. J'ai donc été surpris de constater que Python n'était pas vraiment mentionné dans ce question, et quand elle était mentionnée, ce n'était généralement pas très positif. Cependant, peu de raisons ont été données pour cela (le manque de filtrage et les types de données algébriques ont été mentionnés). Ma question est donc la suivante : pourquoi Python n'est-il pas très bon pour la programmation fonctionnelle ? Y a-t-il d'autres raisons que l'absence de filtrage et de types de données algébriques ? Ou ces concepts sont-ils si importants pour la programmation fonctionnelle qu'un langage qui ne les prend pas en charge ne peut être classé que comme un langage de programmation fonctionnelle de second ordre ? (Gardez à l'esprit que mon expérience de la programmation fonctionnelle est assez limitée).
Réponses
Trop de publicités?La question à laquelle vous faites référence demande quels langages favorisent à la fois la programmation OO et fonctionnelle. Python ne promouvoir programmation fonctionnelle, même si elle travaux assez bien.
Le meilleur argument contre La programmation fonctionnelle en Python est que les cas d'utilisation de l'impératif/OO sont soigneusement pris en compte par Guido, alors que les cas d'utilisation de la programmation fonctionnelle ne le sont pas. Lorsque j'écris du Python impératif, c'est l'un des plus beaux langages que je connaisse. Quand j'écris du Python fonctionnel, il devient aussi laid et désagréable que n'importe quel langage moyen qui n'a pas de fonction BDFL .
Ce qui ne veut pas dire que c'est mauvais, mais simplement que vous devez travailler plus dur que si vous passiez à un langage qui promeut la programmation fonctionnelle ou à l'écriture de Python OO.
Voici les choses fonctionnelles qui me manquent dans Python :
- Correspondance de motifs
- Récursion de la queue
- Grande bibliothèque de fonctions de liste
- Classe fonctionnelle du dictionnaire
- Séchage automatique
- Une façon concise de composer des fonctions
- Listes paresseuses
- syntaxe d'expression simple et puissante (la syntaxe de bloc simple de Python empêche Guido de l'ajouter)
- L'absence de filtrage et de récursion de queue signifie que vos algorithmes de base doivent être écrits de manière impérative. La récursion est laide et lente en Python.
- Une petite bibliothèque de listes et l'absence de dictionnaires fonctionnels signifient que vous devez écrire beaucoup de choses vous-même.
- L'absence de syntaxe pour le curage ou la composition signifie que le style sans point est à peu près aussi riche en ponctuation que le passage explicite d'arguments.
- Les itérateurs au lieu des listes paresseuses signifient que vous devez savoir si vous voulez l'efficacité ou la persistance, et disperser les appels à
list
si vous voulez de la persistance. (Les itérateurs sont utilisés une seule fois) - La syntaxe impérative simple de Python, ainsi que son analyseur simple LL1, signifie qu'une meilleure syntaxe pour les expressions if et lambda est fondamentalement impossible. Guido aime cette façon de faire, et je pense qu'il a raison.
Guido a une bonne explication à ce sujet ici . Voici la partie la plus pertinente :
Je n'ai jamais considéré que Python était fortement influencé par les langages fonctionnels fonctionnels, peu importe ce que les gens disent ou ce que les gens pensent. J'étais beaucoup plus familier avec les langages impératifs comme le C et Algol 68 et bien que j'aie fait des fonctions des objets de première classe, je ne voyais pas Python comme un langage de programmation de programmation fonctionnel. Cependant, plus tôt il était clair que les utilisateurs voulaient faire faire beaucoup plus avec les listes et les fonctions.
...
Il est également intéressant de noter que même même si je n'avais pas envisagé Python comme un langage fonctionnel, l'introduction des des fermetures a été utile dans le développement de nombreuses autres avancées de programmation. Par exemple, certains aspects des classes de style nouveau, des décorateurs et d'autres fonctionnalités modernes reposent sur cette capacité.
Enfin, même si un certain nombre de fonctionnalités de programmation fonctionnelle ont été introduites au fil des ans, Python ne dispose toujours pas de certaines fonctionnalités présentes dans "vrais" langages de programmation fonctionnelle fonctionnels. Par exemple, Python ne n'effectue pas certains types d'optimisations optimisations (par exemple, la récursion de queue). D'une manière générale, en raison de la nature extrêmement nature extrêmement dynamique de Python, il est impossible d'effectuer le type d'optimisation à la compilation connues des langages fonctionnels comme Haskell ou ML. Et ce n'est pas grave.
Je retire deux choses de tout ça :
- Le créateur du langage ne considère pas vraiment Python comme un langage fonctionnel. Par conséquent, il est possible de voir des fonctionnalités "ressemblant à du fonctionnel", mais il est peu probable que vous voyiez quelque chose de définitivement fonctionnel.
- La nature dynamique de Python empêche certaines des optimisations que l'on voit dans d'autres langages fonctionnels. Il est vrai que Lisp est tout aussi dynamique (si ce n'est plus) que Python, ce n'est donc qu'une explication partielle.
Scheme n'a pas de types de données algébriques ou de correspondance de motifs mais c'est certainement un langage fonctionnel. Les choses gênantes à propos de Python du point de vue de la programmation fonctionnelle :
-
Lambdas estropiées. Étant donné que les lambdas ne peuvent contenir qu'une expression et que vous ne pouvez pas tout faire aussi facilement dans un contexte d'expression, cela signifie que les fonctions que vous pouvez définir "à la volée" sont limitées.
-
Les Ifs sont des déclarations, pas des expressions. Cela signifie, entre autres, que vous ne pouvez pas avoir une lambda avec un If à l'intérieur. (Ceci est corrigé par les ternaires dans Python 2.5, mais c'est laid).
-
Guido menace de supprimer la carte, le filtre et la réduction de temps en temps
D'un autre côté, Python dispose de fermetures lexicales, de lambdas et de compréhensions de listes (qui sont vraiment un concept "fonctionnel", que Guido l'admette ou non). Je fais beaucoup de programmation de "style fonctionnel" en Python, mais je ne dirais pas que c'est idéal.
Je ne qualifierais jamais Python de "fonctionnel", mais chaque fois que je programme en Python, le code finit invariablement par être presque purement fonctionnel.
Certes, c'est surtout dû à la très bonne compréhension de la liste. Je ne suggérerais donc pas nécessairement Python comme langage de programmation fonctionnelle, mais je suggérerais la programmation fonctionnelle à quiconque utilise Python.
Laissez-moi vous démontrer avec un morceau de code tiré d'une réponse à une question "fonctionnelle". Question sur Python sur le SO
Python :
def grandKids(generation, kidsFunc, val):
layer = [val]
for i in xrange(generation):
layer = itertools.chain.from_iterable(itertools.imap(kidsFunc, layer))
return layer
Haskell :
grandKids generation kidsFunc val =
iterate (concatMap kidsFunc) [val] !! generation
La principale différence ici est que la bibliothèque standard de Haskell possède des fonctions utiles pour la programmation fonctionnelle : dans ce cas, il s'agit de iterate
, concat
et (!!)