Quelle est la différence entre la programmation procédurale et la programmation fonctionnelle?
J'ai lu les articles de Wikipédia pour les deux programmation procédurale et programmation fonctionnelle, mais je suis encore un peu confus. Quelqu'un pourrait-il la faire bouillir jusqu'à l'âme?
- Wikipédia implique que FP est un sous-ensemble de (est toujours) la programmation déclarative, mais que n'est pas vrai et débordait la taxonomie de la propriété intellectuelle vs DP.
Vous devez vous connecter pour publier un commentaire.
Un langage fonctionnel (idéalement) vous permet d'écrire une fonction mathématique, c'est à dire une fonction qui prend n arguments et retourne une valeur. Si le programme est exécuté, cette fonction est logiquement évalué en tant que de besoin.1
Un langage procédural, d'autre part, effectue une série de séquentielle étapes. (Il y a un moyen de transformer une logique séquentielle dans une logique fonctionnelle appelée continuation passing style.)
En conséquence, d'un point de vue purement fonctionnel programme donne toujours la même valeur pour une entrée, et l'ordre d'évaluation n'est pas bien définie; ce qui signifie que les valeurs incertaines, comme la saisie de l'utilisateur ou de valeurs aléatoires sont dur de modèle purement fonctionnelle des langues.
1 Comme tout le reste dans cette réponse, c'est une généralisation. La propriété de l'évaluation d'un calcul lorsque son résultat est nécessaire plutôt que de façon séquentielle où il est appelé est connu comme “la paresse”, et non pas tous les langages fonctionnels sont en fait universellement paresseux, ni la paresse limité à la programmation fonctionnelle. Plutôt, la description donnée ici fournit un “schéma mental” à une réflexion sur les différents styles de programmation qui ne sont pas distinctes et opposées catégories, mais plutôt fluide idées.
Fondamentalement, les deux styles sont comme le Yin et le Yang. On est organisé, tandis que les autres chaotique. Il existe des situations où la programmation Fonctionnelle est le choix évident, et d'autres situations de Procédure de programmation est le meilleur choix. C'est pourquoi il y a au moins deux langues qui ont récemment sorti avec une nouvelle version, qui embrasse les deux styles de programmation. ( Perl 6 et D 2 )
De procédure:
Perl 6
D 2
Fonctionnelle:
Haskell
( copié à partir de Wikipédia );
ou en une seule ligne:
Perl 6
D 2
Note de côté:
Factorielle est effectivement un bon exemple pour montrer comment il est facile de créer de nouveaux opérateurs de Perl 6 de la même façon que vous créez une sous-routine. Cette fonctionnalité est tellement ancrée en Perl 6 que la plupart des opérateurs dans le Rakudo de mise en œuvre sont définies de cette façon. Il vous permet également d'ajouter vos propres multi candidats aux opérateurs existants.
Cet exemple montre également la gamme de la création (
2..$n
) et la liste de réduction de la méta-opérateur ([ OPERATOR ] LIST
) combiné avec le numérique infix opérateur de multiplication. (*
)Il montre aussi que vous pouvez mettre
--> UInt
dans la signature, au lieu dereturns UInt
après.( Vous pouvez vous en sortir avec le début de la gamme, avec
2
comme le multiplier "opérateur" sera de retour1
lorsqu'il est appelé sans arguments )sub postfix:<!> ($n) { [*] 1..$n }
$n
/n
a pas été modifié à partir de l'appelant point de vue.sub foo( $a, $b ){ $a + $b }
Je n'ai jamais vu de cette définition, donnée ailleurs, mais je pense que cela résume les différences donné ici assez bien:
Fonctionnelle programmation met l'accent sur expressions
De procédure programmation met l'accent sur états
Expressions ont des valeurs. Un programme fonctionnel est une expression qui est la valeur est une séquence d'instructions de l'ordinateur à effectuer.
États n'ont pas de valeurs et, au lieu de modifier l'état de certains conceptuel de la machine.
Dans un rôle purement fonctionnel de la langue il n'y aurait pas de déclarations, dans le sens où il n'y a aucun moyen de manipuler l'état (ils peuvent encore avoir une construction syntaxique nommé "déclaration", mais à moins qu'il manipule état, je n'appellerais pas ça une déclaration dans ce sens). Dans un but purement procédurale de la langue il n'y aurait pas d'expressions, tout serait une instruction qui manipule l'état de la machine.
Haskell serait un exemple d'un point de vue purement fonctionnel de la langue, car il n'y a aucun moyen de manipuler l'état. Code Machine serait un exemple d'un caractère purement procédural de la langue, parce que tout, dans un programme est une déclaration qui manipule l'état des registres et de la mémoire de la machine.
La confusion, c'est que la grande majorité des langages de programmation contenir les deux des expressions et instructions, vous permettant de mixer des paradigmes. Les langues peuvent être classés comme des plus fonctionnelles ou plus de procédure basée sur la façon dont beaucoup ils encouragent l'utilisation de déclarations vs expressions.
Par exemple, C serait plus fonctionnel que le COBOL en raison d'un appel de fonction est une expression, alors que l'appel d'un sous programme en COBOL est un énoncé (qui manipule l'état des variables partagées et ne retourne pas une valeur). Python serait plus fonctionnel que C parce qu'elle permet d'exprimer la logique conditionnelle comme une expression à l'aide de court-circuit d'évaluation (test && path1 || path2, par opposition à si consolidés). Schéma serait plus fonctionnel que le Python parce que tout système est une expression.
Vous pouvez toujours écrire dans un style fonctionnel dans une langue qui encourage la procédure de paradigme et vice versa. C'est juste plus difficile et/ou plus difficile à écrire dans un paradigme qui n'est pas encouragé par le langage.
En sciences de l'informatique, de la programmation fonctionnelle est un paradigme de programmation qui traite de calcul de l'évaluation des fonctions mathématiques et évite d'état et de données mutable. Il met l'accent sur l'application de fonctions, en contraste avec la programmation procédurale style qui met l'accent sur les changements dans l'état.
GetUserContext()
dans la fonction, le contexte de l'utilisateur serait passé. Est-ce de la programmation fonctionnelle? Merci à l'avance.Je crois que la procédure/fonctionnel/de l'objectif de la programmation, à propos de la façon d'aborder un problème.
Le premier style tout planifier dans les étapes, et résout le problème en mettant en œuvre une étape (une procédure) à la fois. D'autre part, la programmation fonctionnelle met l'accent sur le " diviser pour mieux régner approche, où le problème est divisé en sous-problème, puis chaque sous-problème est résolu (création d'une fonction pour résoudre le sous-problème) et les résultats sont combinés pour créer la réponse pour l'ensemble du problème. Enfin, l'Objectif de la programmation imiter le monde réel par la création d'un mini-monde à l'intérieur de l'ordinateur avec de nombreux objets, dont chacun a une (un peu), des caractéristiques uniques, et interagit avec les autres. À partir de ces interactions, le résultat allait émerger.
Chaque style de programmation a ses propres avantages et inconvénients. Donc, faire quelque chose comme la "pure programmation" (c'est à dire purement une question de procédure, personne ne fait cela, par la voie, qui est une sorte de bizarre ou purement fonctionnelle ou purement objective) est très difficile, si pas impossible, à l'exception de quelques problèmes élémentaires spécialement conçu pour démontrer l'avantage d'un style de programmation (par conséquent, nous appelons ceux qui aiment la pureté de la "petite bite" :D).
Puis, à partir de ces styles, nous avons des langages de programmation qui est conçu pour optimisé pour chaque style. Par exemple, l'Assemblage est tout au sujet de la procédure. Ok, la plupart des premières langues de procédure, non seulement de l'Asm, comme en C, Pascal, (et Fortran, j'ai entendu). Ensuite, nous avons toutes les fameux Java dans l'objectif de l'école (en Fait, Java et C# est aussi dans une classe appelée "axé sur l'argent", mais qui est sujet d'une autre discussion). Aussi l'objectif est de Smalltalk. Fonctionnelle de l'école, on aurait presque "fonctionnelle" (certains les considéraient comme impur) Lisp de la famille et de la ML de la famille et de nombreux "purement fonctionnelle" Haskell, Erlang, etc. Par ailleurs, il existe de nombreux langages tels que Perl, Python, Ruby.
Étendre sur Konrad commentaire:
De ce fait, le code fonctionnel est généralement plus facile à paralléliser. Comme il y a (généralement) pas d'effets secondaires de l'fonctions, et ils ont (en général), suffit d'agir sur leurs arguments, beaucoup de problèmes de concurrence en aller.
De la programmation fonctionnelle est également utilisé lorsque vous avez besoin d'être capable de prouver votre code est correct. C'est beaucoup plus difficile à faire avec programmation procédurale (pas facile avec fonctionnel, mais encore plus facile).
Avertissement: je n'ai pas utilisé de la programmation fonctionnelle dans les années, et c'est seulement récemment commencé à le regarder à nouveau, donc je ne pourrais pas être tout à fait correct ici. 🙂
Une chose que je n'avais pas vu vraiment de souligner ici, c'est que moderne et fonctionnel langages comme Haskell vraiment plus sur la première classe des fonctions pour le contrôle de flux explicite que la récursivité. Vous n'avez pas besoin de définir factorielle récursive en Haskell, comme on l'a fait ci-dessus. Je pense que quelque chose comme
est parfaitement idiomatique de la construction, et beaucoup plus proche dans l'esprit à l'aide d'une boucle qu'à l'utilisation explicite de la récursivité.
Programmation fonctionnelle est identique à la procédure de programmation dans lequel les variables globales sont pas utilisé.
Langues procédurales ont tendance à garder une trace de l'état (à l'aide de variables) et ont tendance à s'exécuter comme une séquence d'étapes. Purement fonctionnelle langues ne pas garder une trace de l'état, l'utilisation des valeurs inaltérables, et ont tendance à s'exécuter comme une série de dépendances. Dans de nombreux cas, l'état de la pile d'appel contiendra les informations qui serait équivalente à celle qui serait stocké dans les variables d'état dans le code de procédure.
La récursivité est un exemple classique de style fonctionnel de la programmation.
Konrad dit:
L'ordre d'évaluation dans un but purement fonctionnel programme peut être dur(er) à raison d'environ (en particulier avec la paresse) ou même sans importance, mais je pense que le fait de dire qu'il n'est pas bien défini donne l'impression que vous ne pouvez pas savoir si votre programme est d'aller travailler à tous!
Peut-être une meilleure explication serait que les flux de contrôle dans les programmes fonctionnels est basée sur le moment où la valeur d'une fonction, les arguments sont nécessaires. La Bonne Chose à propos de ce que, dans bien écrit, les programmes, l'état devient explicite: chaque fonction dresse la liste de ses entrées de paramètres au lieu de l'arbitraire munging de l'état global. Donc, à un certain niveau, il est plus facile de raisonner sur l'ordre de l'évaluation par rapport à une seule fonction à la fois. Chaque fonction peut ignorer le reste de l'univers et de se concentrer sur ce qu'il doit faire. Une fois combinés, les fonctions sont garantis pour fonctionner de la même[1] comme ils le feraient dans l'isolement.
La solution au problème de saisie purement fonctionnelle des programmes est d'intégrer un langage impératif comme un DSL à l'aide de suffisamment puissant abstraction. Dans l'impératif (ou non-fonctionnels purs) langues ce n'est pas nécessaire car vous pouvez "tricher" et de passer de l'état de manière implicite et de l'ordre d'évaluation est explicite (si vous l'aimez ou pas). En raison de cette "tricherie" et forcé d'évaluation de tous les paramètres pour chaque fonction, dans les langages impératifs, 1), vous perdez la possibilité de créer votre propre flux de contrôle mécanismes (sans macros), 2) le code n'est pas intrinsèquement thread-safe et/ou parallélisables par défaut, 3) et la mise en œuvre de quelque chose comme annuler (le voyage dans le temps) prend soin de travail (impératif programmeur doit stocker une recette pour faire de l'ancienne valeur(s) de retour!), alors que la pure programmation fonctionnelle vous permet d'acheter toutes ces choses—et quelques autres que j'ai oublié—"gratuitement".
J'espère que cela ne sonne pas comme le fanatisme, je voulais juste ajouter un peu de perspective. La programmation impérative et surtout mixte paradigme de la programmation dans des langages tels que C# 3.0 sont toujours totalement des moyens efficaces de faire les choses et il n'y a pas de solution miracle.
[1] ... sauf peut-être concernant l'utilisation de la mémoire (cf. foldl et foldl' en Haskell).
Étendre sur Konrad commentaire:
Certains langages fonctionnels ont ce qu'on appelle l'Évaluation différée. Ce qui signifie qu'une fonction n'est pas exécutée jusqu'à ce que la valeur est nécessaire. Jusqu'à ce que la fonction elle-même est ce qui est passé autour de.
Les langages procéduraux sont l'étape 1 étape 2 étape 3... si à l'étape 2, vous dites ajouter 2 + 2, il le fait à droite, puis. Dans l'évaluation différée vous dirais ajouter 2 + 2, mais si le résultat n'est jamais utilisé, il ne fait jamais le plus.
Fonctionnelle De Programmation
Programmation Procédurale
function_to_add_one
est une fonctionprocedure_to_add_one
est une procédureMême si vous exécutez la fonction cinq fois, à chaque fois qu'il sera de retour 2
Si vous exécutez le procédure cinq fois, à la fin du cinquième terme, il sera vous donner 6.
Si vous en avez l'occasion, je le conseille pour obtenir une copie du Lisp/Scheme, et de faire des projets. La plupart des idées qui ont récemment devenue bandwagons ont été exprimés en Lisp il y a des décennies: la programmation fonctionnelle, les continuations (que les fermetures), la collecte des ordures, même XML.
Alors que ce serait un bon moyen d'obtenir une longueur d'avance sur tous ces courants d'idées, et un peu plus d'ailleurs, à l'instar de calcul symbolique.
Vous devez savoir ce que la programmation fonctionnelle est bon pour, et ce qui n'est pas bon pour. Il n'est pas bon pour tout. Certains problèmes sont mieux exprimés en termes d'effets secondaires, où la même question donne differet réponses selon le moment où il est demandé.
@Creighton:
En Haskell il n'y est une fonction de la bibliothèque appelé produit:
ou tout simplement:
de sorte que le "idiomatiques" factorielle
serait tout simplement
Programmation procédurale divise les séquences d'états et à la condition que les constructions en blocs distincts appelés les procédures qui sont paramétrées sur des arguments (non-fonctionnelle) des valeurs.
De la programmation fonctionnelle est la même sauf que les fonctions sont des valeurs de première classe, de sorte qu'ils peuvent être passés comme arguments à d'autres fonctions et renvoyé que les résultats des appels de fonction.
Note que la programmation fonctionnelle est une généralisation de la programmation procédurale, dans cette interprétation. Cependant, une minorité d'interpréter "programmation fonctionnelle" pour signifier effet secondaire qui est tout à fait différent, mais hors de propos, pour tous les principaux langages fonctionnels à l'exception de Haskell.
Pour Comprendre la différence, il faut comprendre que "le parrain" paradigme de la procédure et de la programmation fonctionnelle est la la programmation impérative.
Fondamentalement programmation procédurale est simplement une manière de structurer les programmes impératifs dont la principale méthode de l'abstraction est la "procédure". (ou "fonction" dans certains langages de programmation). Même la Programmation Orientée Objet est simplement une autre façon de structurer un programme impératif, où l'état est encapsulé dans des objets, de devenir un objet avec un "état actuel", en plus cet objet est un ensemble de fonctions, méthodes, et d'autres choses qui vous permettent de le programmeur de manipuler ou de mettre à jour l'état.
Maintenant, en ce qui concerne la programmation fonctionnelle, la gist dans son approche, c'est qu'il identifie quelles sont les valeurs à prendre et la façon dont ces valeurs doivent être transférés. (il n'y a pas d'état, et de l'absence de données mutable comme il faut des fonctions de première classe, les valeurs et les passer en paramètres à d'autres fonctions).
PS: la compréhension de chaque paradigme de programmation est utilisé pour préciser les différences entre chacun d'eux.
PSS: À la fin de la journée, paradigmes de programmation sont simplement différentes approches de résolution de problèmes.
PSS: cette quora réponse a une grande explication.
Aucune des réponses ici montrent idiomatiques de la programmation fonctionnelle. La factorielle récursive réponse est idéal pour la représentation de la récursivité de la FP, mais la majorité de code n'est pas récursive, donc je ne pense pas que la réponse est pleinement représentatif.
Disons que vous avez un des tableaux de chaînes de caractères, et chaque chaîne représente un entier tel que "5" ou "-200". Vous voulez vérifier ce tableau de chaînes de caractères à l'encontre de vos internes de cas de test (à l'Aide de comparaison des entiers). Les deux solutions sont indiqués ci-dessous
De procédure
Fonctionnelle
Tandis que pur les langages fonctionnels sont généralement à la recherche des langues (Comme le réel-monde aime libre d'effets secondaires), le monde réel et les langages procéduraux utilisera le plus simple syntaxe fonctionnelle lorsque cela est approprié.
C'est généralement mis en œuvre avec une bibliothèque externe comme Lodash, ou intégré disponible avec de nouveaux langages comme La rouille. Le levage lourd de la programmation fonctionnelle est fait avec des fonctions/concepts comme
map
,filter
,reduce
,currying
,partial
, les trois derniers de que vous pouvez consulter pour plus de compréhension.Additif
Pour être utilisé à l'état sauvage, le compilateur devra normalement travailler sur la façon de convertir la version fonctionnelle dans la version procédurale à l'interne, appel de fonction de charge est trop élevée. Récursive des cas tels que la factorielle montre va utiliser des trucs comme appel tail pour supprimer O(n) l'utilisation de la mémoire. Le fait qu'il n'y a pas d'effets secondaires permet fonctionnelle compilateurs pour mettre en œuvre les
&& ret
d'optimisation, même lorsque le.reduce
est la dernière. À l'aide de Lodash en JS, évidemment, ne permettent pas de l'optimisation, c'est donc un coup à la performance (ce Qui n'est généralement pas un souci avec le développement web). Les langues, comme la Rouille, permettra d'optimiser en interne (Et qui ont des fonctions telles quetry_fold
pour aider&& ret
optimisation).