La plupart des langages traditionnels, y compris les langages de programmation orientée objet (POO) tels que C #, Visual Basic, C ++ et Java ont été conçus pour prendre principalement en charge la programmation impérative (procédurale), tandis que les langages de type Haskell / gofer sont purement fonctionnels. Quelqu'un peut-il expliquer quelle est la différence entre ces deux modes de programmation?
Je sais que le choix du mode de programmation dépend des besoins des utilisateurs, mais pourquoi est-il recommandé d'apprendre des langages de programmation fonctionnels?
oop
functional-programming
Swapnil Kotwal
la source
la source
Réponses:
Définition: Un langage impératif utilise une séquence d'énoncés pour déterminer comment atteindre un certain objectif. On dit que ces instructions changent l'état du programme lorsque chacune est exécutée à son tour.
Exemples: Java est un langage impératif. Par exemple, un programme peut être créé pour ajouter une série de nombres:
Chaque instruction modifie l'état du programme, de l'attribution de valeurs à chaque variable à l'ajout final de ces valeurs. En utilisant une séquence de cinq instructions, le programme est explicitement dit comment additionner les nombres 5, 10 et 15 ensemble.
Langages fonctionnels: Le paradigme de programmation fonctionnelle a été explicitement créé pour prendre en charge une approche purement fonctionnelle de la résolution de problèmes. La programmation fonctionnelle est une forme de programmation déclarative.
Avantages des fonctions pures: La principale raison d'implémenter des transformations fonctionnelles en tant que fonctions pures est que les fonctions pures sont composables: c'est-à-dire autonomes et sans état. Ces caractéristiques apportent un certain nombre d'avantages, notamment les suivants: Meilleure lisibilité et maintenabilité. En effet, chaque fonction est conçue pour accomplir une tâche spécifique compte tenu de ses arguments. La fonction ne repose sur aucun état externe.
Développement répétitif plus facile. Le code étant plus facile à refactoriser, les modifications apportées à la conception sont souvent plus faciles à implémenter. Par exemple, supposons que vous écriviez une transformation compliquée, puis que vous vous rendiez compte que du code est répété plusieurs fois dans la transformation. Si vous refactorisez par une méthode pure, vous pouvez appeler votre méthode pure à volonté sans vous soucier des effets secondaires.
Tests et débogage plus faciles. Étant donné que les fonctions pures peuvent plus facilement être testées isolément, vous pouvez écrire du code de test qui appelle la fonction pure avec des valeurs typiques, des cas de bord valides et des cas de bord invalides.
Pour les personnes OOP ou les langues impératives:
Les langages orientés objet sont bons lorsque vous avez un ensemble fixe d'opérations sur les choses et que votre code évolue, vous ajoutez principalement de nouvelles choses. Cela peut être accompli en ajoutant de nouvelles classes qui implémentent des méthodes existantes et les classes existantes sont laissées seules.
Les langages fonctionnels sont bons lorsque vous avez un ensemble fixe de choses et que votre code évolue, vous ajoutez principalement de nouvelles opérations sur des éléments existants. Cela peut être accompli en ajoutant de nouvelles fonctions qui calculent avec les types de données existants et les fonctions existantes sont laissées seules.
Les inconvénients:
Le choix de la méthode de programmation dépend des besoins des utilisateurs, il n'y a donc de mal que lorsque les utilisateurs ne choisissent pas la bonne manière.
Lorsque l'évolution va dans le mauvais sens, vous avez des problèmes:
la source
Voici la différence:
Impératif:
... et ainsi de suite ...
Déclaratif, dont fonctionnel est une sous-catégorie:
... et ainsi de suite ...
Résumé: Dans les langages impératifs, vous indiquez à l'ordinateur comment changer les bits, les octets et les mots de sa mémoire et dans quel ordre. Dans les fonctions fonctionnelles, nous disons à l'ordinateur ce que sont les choses, les actions, etc. Par exemple, nous disons que la factorielle de 0 est 1, et la factorielle de tout autre nombre naturel est le produit de ce nombre par la factorielle de son prédécesseur. Nous ne disons pas: pour calculer la factorielle de n, réserver une région mémoire et y stocker 1, puis multiplier le nombre dans cette région mémoire avec les nombres 2 à n et stocker le résultat au même endroit, et à la fin, la région mémoire contiendra la factorielle.
la source
La plupart des langages modernes sont à des degrés divers à la fois impératifs et fonctionnels, mais pour mieux comprendre la programmation fonctionnelle, il sera préférable de prendre un exemple de langage fonctionnel pur comme Haskell en contraste avec un code impératif dans un langage pas si fonctionnel comme java / c #. Je pense qu'il est toujours facile d'expliquer par l'exemple, alors en voici un.
Programmation fonctionnelle: calculer factorielle de n soit n! soit nx (n-1) x (n-2) x ... x 2 X 1
Notez que Haskel autorise la surcharge de fonction au niveau de la valeur de l'argument. Voici maintenant un exemple de code impératif avec un degré croissant d'impérativité:
Cette lecture peut être une bonne référence pour comprendre comment le code impératif se concentre davantage sur la manière dont la partie, l'état de la machine (i dans la boucle for), l'ordre d'exécution, le contrôle de flux.
Le dernier exemple peut être considéré comme du code java / c # lang grossièrement et la première partie comme une limitation du langage lui-même contrairement à Haskell pour surcharger la fonction par valeur (zéro) et par conséquent, on peut dire qu'il ne s'agit pas d'un langage fonctionnel puriste, d'autre part part, vous pouvez dire qu'il prend en charge prog fonctionnel. dans une certaine mesure.
Divulgation: aucun des codes ci-dessus n'est testé / exécuté mais, espérons-le, devrait être assez bon pour transmettre le concept; J'apprécierais également des commentaires pour une telle correction :)
la source
return n * factorial(n-1);
?n * (n-1)
La programmation fonctionnelle est une forme de programmation déclarative, qui décrit la logique du calcul et l'ordre d'exécution est complètement désaccentué.
Problème: je veux changer cette créature de cheval en girafe.
Chaque élément peut être exécuté dans n'importe quel ordre pour produire le même résultat.
La programmation impérative est procédurale. L'état et l'ordre sont importants.
Problème: je veux garer ma voiture.
Chaque étape doit être effectuée pour arriver au résultat souhaité. Tirer dans le garage alors que la porte de garage est fermée entraînerait une porte de garage cassée.
la source
La programmation fonctionnelle est une «programmation avec des fonctions», où une fonction a certaines propriétés mathématiques attendues, y compris la transparence référentielle. De ces propriétés découlent d'autres propriétés, en particulier des étapes de raisonnement familières permises par la substituabilité qui conduisent à des preuves mathématiques (c'est-à-dire justifiant la confiance dans un résultat).
Il s'ensuit qu'un programme fonctionnel n'est qu'une expression.
Vous pouvez facilement voir le contraste entre les deux styles en notant les endroits dans un programme impératif où une expression n'est plus référentiellement transparente (et n'est donc pas construite avec des fonctions et des valeurs, et ne peut elle-même faire partie d'une fonction). Les deux endroits les plus évidents sont: la mutation (par exemple des variables) d'autres effets secondaires flux de contrôle non local (par exemple des exceptions)
Sur ce cadre de programmes en tant qu'expressions qui sont composés de fonctions et de valeurs, est construit tout un paradigme pratique de langages, de concepts, de «modèles fonctionnels», de combinateurs et de divers systèmes de types et algorithmes d'évaluation.
Selon la définition la plus extrême, presque tous les langages, même C ou Java, peuvent être qualifiés de fonctionnels, mais les gens réservent généralement le terme aux langages avec des abstractions spécifiquement pertinentes (telles que des fermetures, des valeurs immuables et des aides syntaxiques telles que la correspondance de modèles). En ce qui concerne l'utilisation de la programmation fonctionnelle, elle implique l'utilisation de fonctins et construit du code sans aucun effet secondaire. utilisé pour écrire des preuves
la source
Le style de programmation impératif a été pratiqué dans le développement Web de 2005 à 2013.
Avec la programmation impérative, nous avons écrit du code qui répertorie exactement ce que notre application doit faire, étape par étape.
Le style de programmation fonctionnelle produit de l'abstraction grâce à des méthodes intelligentes de combinaison de fonctions.
Il est fait mention de la programmation déclarative dans les réponses et à ce sujet, je dirai que la programmation déclarative énumère certaines règles que nous devons suivre. Nous fournissons ensuite ce que nous appelons un état initial à notre application et nous laissons ces règles définir le comportement de l'application.
Maintenant, ces descriptions rapides n'ont probablement pas beaucoup de sens, alors passons en revue les différences entre la programmation impérative et déclarative en parcourant une analogie.
Imaginez que nous ne construisons pas de logiciels, mais que nous préparons des tartes pour gagner notre vie. Peut-être que nous sommes de mauvais boulangers et que nous ne savons pas comment préparer une délicieuse tarte comme nous le devrions.
Alors notre patron nous donne une liste de directions, ce que nous appelons une recette.
La recette nous dira comment faire une tarte. Une recette est écrite dans un style impératif comme ceci:
La recette déclarative ferait ce qui suit:
1 tasse de farine, 1 œuf, 1 tasse de sucre - état initial
Règles
Les approches impératives sont donc caractérisées par des approches étape par étape. Vous commencez par la première étape et passez à l'étape 2 et ainsi de suite.
Vous vous retrouvez finalement avec un produit final. Donc, pour faire cette tarte, nous prenons ces ingrédients, les mélangons, nous les mettons dans une casserole et au four et vous obtenez votre produit final.
Dans un monde déclaratif, c'est différent.Dans la recette déclarative, nous séparerions notre recette en deux parties distinctes, en commençant par une partie qui répertorie l'état initial de la recette, comme les variables. Donc nos variables ici sont les quantités de nos ingrédients et leur type.
Nous prenons l'état initial ou les ingrédients initiaux et leur appliquons certaines règles.
Nous prenons donc l'état initial et les passons à travers ces règles encore et encore jusqu'à ce que nous ayons une tarte à la rhubarbe et aux fraises prête à manger ou autre.
Donc, dans une approche déclarative, il faut savoir structurer correctement ces règles.
Donc, les règles que nous pourrions vouloir examiner nos ingrédients ou indiquer, si elles sont mélangées, les mettre dans une casserole.
Avec notre état initial, cela ne correspond pas car nous n'avons pas encore mélangé nos ingrédients.
Donc, la règle 2 dit, s'ils ne sont pas mélangés, mélangez-les dans un bol. OK ouais cette règle s'applique.
Maintenant, nous avons un bol d'ingrédients mélangés comme notre état.
Maintenant, nous appliquons à nouveau ce nouvel état à nos règles.
Donc, la règle 1 dit que si les ingrédients sont mélangés, placez-les dans une casserole, d'accord ouais maintenant la règle 1 s'applique, faisons-le.
Maintenant, nous avons ce nouvel état où les ingrédients sont mélangés et dans une casserole. La règle 1 n'est plus pertinente, la règle 2 ne s'applique pas.
La règle 3 dit que si les ingrédients sont dans une casserole, placez-les dans le four, c'est bien cette règle qui s'applique à ce nouvel état, faisons-le.
Et nous nous retrouvons avec une délicieuse tarte aux pommes chaude ou autre.
Maintenant, si vous êtes comme moi, vous vous demandez peut-être pourquoi ne faisons-nous pas encore de programmation impérative. C'est logique.
Eh bien, pour les flux simples, oui, mais la plupart des applications Web ont des flux plus complexes qui ne peuvent pas être correctement capturés par une conception de programmation impérative.
Dans une approche déclarative, nous pouvons avoir des ingrédients initiaux ou un état initial comme
textInput=“”
, une seule variable.Peut-être que la saisie de texte commence par une chaîne vide.
Nous prenons cet état initial et l'appliquons à un ensemble de règles définies dans votre application.
Si un utilisateur entre du texte, mettez à jour l'entrée de texte. Eh bien, pour le moment, cela ne s'applique pas.
Si le modèle est rendu, calculez le widget.
Eh bien, rien de tout cela ne s'applique, donc le programme attendra juste qu'un événement se produise.
Ainsi, à un moment donné, un utilisateur met à jour la saisie de texte, puis nous pourrions appliquer la règle numéro 1.
Nous pouvons mettre à jour cela pour
“abcd”
Nous venons donc de mettre à jour nos mises à jour de texte et de textInput, la règle numéro 2 ne s'applique pas, la règle numéro 3 dit que si l'entrée de texte est mise à jour, ce qui vient de se produire, puis restituer le modèle, puis nous revenons à la règle 2 qui dit si le modèle est rendu , calculez le widget, d'accord, calculons le widget.
En général, en tant que programmeurs, nous voulons nous efforcer d'obtenir des conceptions de programmation plus déclaratives.
L'impératif semble plus clair et évident, mais une approche déclarative s'adapte très bien aux applications plus importantes.
la source
• Langues impératives:
Exécution efficace
Sémantique complexe
Syntaxe complexe
La concurrence est conçue par un programmeur
Les tests complexes, n'ont pas de transparence référentielle, ont des effets secondaires
• Langages fonctionnels:
Sémantique simple
Syntaxe simple
Exécution moins efficace
Les programmes peuvent être automatiquement créés simultanément
Des tests simples, ont une transparence référentielle, n'ont pas d'effets secondaires
la source
Je pense qu'il est possible d'exprimer la programmation fonctionnelle de manière impérative:
if... else
/switch
instructionsIl y a d'énormes problèmes avec une telle approche:
La programmation fonctionnelle, traitant les fonctions / méthodes comme des objets et embrassant l'apatridie, est née pour résoudre ces problèmes que je crois.
Exemple d'utilisations: applications frontales comme Android, iOS ou logiques d'applications Web incl. communication avec le backend.
Autres défis lors de la simulation de la programmation fonctionnelle avec du code impératif / procédural:
Je crois aussi qu'en fin de compte, le code fonctionnel sera traduit en assemblage ou en code machine, ce qui est impératif / procédural par les compilateurs. Cependant, à moins que vous n'écriviez l'assembly, en tant qu'êtres humains écrivant du code avec un langage de haut niveau / lisible par l'homme, la programmation fonctionnelle est le moyen d'expression le plus approprié pour les scénarios répertoriés
la source
Je sais que cette question est plus ancienne et que d'autres l'ont déjà bien expliqué, je voudrais donner un exemple de problème qui explique la même chose en termes simples.
Problème: Ecrire la table des 1.
Solution: -
Par style impératif: =>
Par style fonctionnel: =>
Explication en style impératif, nous écrivons les instructions plus explicitement et qui peuvent être appelées de manière plus simplifiée.
Où, comme dans le style fonctionnel, les choses qui s'expliquent d'elles-mêmes seront ignorées.
la source