J'ai toujours pensé que la programmation fonctionnelle pouvait se faire en Python. Ainsi, j'ai été surpris que Python n'ait pas obtenu beaucoup de mention dans cette question, et quand elle a été mentionnée, elle n'était normalement pas très positive. Cependant, peu de raisons ont été données à cela (le manque de correspondance des modèles et les types de données algébriques ont été mentionnés). Donc ma question est: pourquoi Python n'est-il pas très bon pour la programmation fonctionnelle? Y a-t-il plus de raisons que son manque de correspondance de motifs 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 langage de programmation fonctionnel de second ordre? (Gardez à l'esprit que mon expérience avec la programmation fonctionnelle est assez limitée.)
la source
Réponses:
La question à laquelle vous faites référence demande quels langages favorisent à la fois l'OO et la programmation fonctionnelle. Python ne favorise pas la programmation fonctionnelle même s'il fonctionne assez bien.
Le meilleur argument contre la programmation fonctionnelle en Python est que les cas d'utilisation impératifs / OO sont soigneusement pris en compte par Guido, contrairement aux cas d'utilisation de la programmation fonctionnelle. Quand j'écris Python impératif, c'est l'un des plus beaux langages que je connaisse. Lorsque j'écris du Python fonctionnel, il devient aussi laid et désagréable que votre langage moyen qui n'a pas de BDFL .
Ce qui ne veut pas dire que c'est mauvais, juste que vous devez travailler plus dur que si vous passiez à un langage qui promeut la programmation fonctionnelle ou passiez à l'écriture OO Python.
Voici les choses fonctionnelles qui me manquent en Python:
list
si vous voulez la persistance. (Les itérateurs sont à usage unique)la source
Guido en a une bonne explication ici . Voici la partie la plus pertinente:
J'en retire deux choses:
la source
Le schéma n'a pas de types de données algébriques ou de correspondance de modèles, mais c'est certainement un langage fonctionnel. Choses ennuyeuses sur Python du point de vue de la programmation fonctionnelle:
Lambdas paralysés. Étant donné que Lambdas ne peut 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 instructions et non des expressions. Cela signifie, entre autres, que vous ne pouvez pas avoir un lambda avec un If à l'intérieur. (Ceci est corrigé par les ternaires dans Python 2.5, mais il semble laid.)
Guido menace de supprimer la carte, de filtrer et de réduire de temps en temps
D'autre part, python a des fermetures lexicales, Lambdas et des listes de compréhension (qui sont vraiment un concept "fonctionnel" que Guido l'admette ou non). Je fais beaucoup de programmation de "style fonctionnel" en Python, mais je dirais à peine que c'est idéal.
la source
Je n'appellerais jamais Python «fonctionnel» mais chaque fois que je programme en Python, le code finit toujours par être presque purement fonctionnel.
Certes, cela est principalement dû à la compréhension extrêmement agréable de la liste. Donc, je ne suggérerais pas nécessairement Python comme langage de programmation fonctionnel, mais je suggérerais une programmation fonctionnelle pour toute personne utilisant Python.
la source
Permettez-moi de démontrer avec un morceau de code tiré d'une réponse à une question Python "fonctionnelle" sur SO
Python:
Haskell:
La principale différence ici est que la bibliothèque standard de Haskell a des fonctions utiles pour la programmation fonctionnelle: dans ce cas
iterate
,concat
et(!!)
la source
grandKids()
corps avec des expressions du générateur:return reduce(lambda a, v: concat((x for x in kidsFunc(v)) for v in a), xrange(generation), [val])
.concat
plus:return reduce(lambda a, v: (x for v in a for x in kidsFunc(v)), xrange(generation), [val])
itertools.chain.from_iterable
Une chose qui est vraiment importante pour cette question (et les réponses) est la suivante: qu'est-ce que l'enfer est la programmation fonctionnelle, et quelles sont les propriétés les plus importantes de celle-ci. Je vais essayer de vous donner mon avis:
La programmation fonctionnelle ressemble beaucoup à l'écriture de mathématiques sur un tableau blanc. Lorsque vous écrivez des équations sur un tableau blanc, vous ne pensez pas à un ordre d'exécution. Il n'y a (généralement) aucune mutation. Vous ne revenez pas le lendemain et regardez-le, et lorsque vous refaites les calculs, vous obtenez un résultat différent (ou vous pouvez, si vous avez bu du café frais :)). Fondamentalement, ce qui est au tableau est là, et la réponse était déjà là lorsque vous avez commencé à écrire des choses, vous n'avez tout simplement pas encore réalisé ce que c'était.
La programmation fonctionnelle ressemble beaucoup à cela; vous ne changez pas les choses, vous évaluez simplement l'équation (ou dans ce cas, "programme") et déterminez quelle est la réponse. Le programme est toujours là, non modifié. La même chose avec les données.
Je classerais les éléments suivants comme les caractéristiques les plus importantes de la programmation fonctionnelle: a) transparence référentielle - si vous évaluez la même déclaration à un autre moment et à un autre endroit, mais avec les mêmes valeurs de variable, cela signifiera toujours la même chose. b) aucun effet secondaire - peu importe combien de temps vous regardez le tableau blanc, l'équation qu'un autre gars regarde sur un autre tableau blanc ne changera pas accidentellement. c) les fonctions sont aussi des valeurs. qui peuvent être transmises et appliquées avec ou à d'autres variables. d) composition de la fonction, vous pouvez faire h = g · f et ainsi définir une nouvelle fonction h (..) qui équivaut à appeler g (f (..)).
Cette liste est dans mon ordre de priorité, donc la transparence référentielle est la plus importante, suivie par aucun effet secondaire.
Maintenant, si vous passez par python et vérifiez à quel point le langage et les bibliothèques prennent en charge et garantissent ces aspects - alors vous êtes en bonne voie pour répondre à votre propre question.
la source
Python est presque un langage fonctionnel. C'est "lite fonctionnel".
Il a des fonctionnalités supplémentaires, il n'est donc pas assez pur pour certains.
Il manque également certaines fonctionnalités, il n'est donc pas assez complet pour certains.
Les fonctionnalités manquantes sont relativement faciles à écrire. Découvrez des articles comme celui-ci sur FP en Python.
la source
Une autre raison non mentionnée ci-dessus est que de nombreuses fonctions et méthodes intégrées de types intégrés modifient un objet mais ne renvoient pas l'objet modifié. Si ces objets modifiés étaient retournés, cela rendrait le code fonctionnel plus propre et plus concis. Par exemple, si some_list.append (some_object) a renvoyé some_list avec some_object en annexe.
la source
En plus d'autres réponses, une des raisons pour lesquelles Python et la plupart des autres langages multi-paradigmes ne sont pas bien adaptés à une véritable programmation fonctionnelle est que leurs compilateurs / machines virtuelles / run-time ne prennent pas en charge l'optimisation fonctionnelle. Ce type d'optimisation est réalisé par le compilateur qui comprend les règles mathématiques. Par exemple, de nombreux langages de programmation prennent en charge un
map
fonction ou une méthode. Il s'agit d'une fonction assez standard qui prend une fonction comme un argument et un itérable comme deuxième argument applique ensuite cette fonction à chaque élément de l'itérable.Quoi qu'il en soit, c'est
map( foo() , x ) * map( foo(), y )
la même chose quemap( foo(), x * y )
. Ce dernier cas est en fait plus rapide que le premier car le premier effectue deux copies alors que le second en effectue une.De meilleurs langages fonctionnels reconnaissent ces relations mathématiques et effectuent automatiquement l'optimisation. Les langages qui ne sont pas dédiés au paradigme fonctionnel ne seront probablement pas optimisés.
la source
map( foo() , x ) * map( foo(), y ) == map( foo(), x * y )
n'est pas vrai pour toutes les fonctions. Par exemple, considérons le cas lors dufoo
calcul d'une dérivée.+
au lieu de*
.