Programmation fonctionnelle contre POO [fermé]

93

J'ai récemment entendu parler de l'utilisation de langages fonctionnels tels que Haskell. Quelles sont les grandes différences, avantages et inconvénients de la programmation fonctionnelle par rapport à la programmation orientée objet?

GSto
la source
27
L'un ne rejette pas l'autre.
mbq
1
@mbq, je comprends qu'elles ne sont pas mutuellement exclusives, mais je voulais simplement essayer de mieux comprendre la différence entre les deux approches.
GSto
Excellente question. Je me demandais aussi à ce sujet.
JohnFx
La programmation fonctionnelle et la programmation orientée objet sont orthogonales les unes aux autres. Vous pouvez avoir les deux dans la même langue. Exemples: Scala, F #, OCaml, etc. Peut-être avez-vous voulu dire fonctionnel vs impératif, comme Jonas l'a suggéré ?
missingfaktor
4
La vraie réponse est - il n'y a pas de "contre" entre eux. Consultez cette question à StackOverflow .
missingfaktor

Réponses:

67

Je dirais qu'il est plus Programmation fonctionnelle vs programmation Impératif .

La plus grande différence est que la programmation impérative concerne le flux de contrôle, tandis que la programmation fonctionnelle concerne le flux de données . Une autre façon de dire est que la programmation fonctionnelle utilise uniquement des expressions, alors que dans la programmation impérative, on utilise à la fois des expressions et des instructions .

Par exemple, dans la programmation impérative, les variables et les boucles sont courantes lors du traitement de l'état, tandis que dans la programmation fonctionnelle , l'état est traité via le passage de paramètres, ce qui évite les effets secondaires et les affectations.

Pseudo-code impératif pour une fonction permettant de calculer la somme d'une liste (la somme est conservée dans une variable):

int sumList(List<int> list) {
    int sum = 0;
    for(int n = 0; n < list.size(); n++) {
        sum = sum + list.get(n);
    }

    return sum;
}

Pseudo-code fonctionnel pour la même fonction (la somme est passée en paramètre):

fun sumList([], sum) = sum
 |  sumList(v::lst, sum) = sumList(lst, v+sum)

Je recommande la présentation Taming Effects with Functional Programming de Simon Peyton-Jones pour une bonne introduction aux concepts fonctionnels.

Jonas
la source
12
Vous devez mentionner que la version fonctionnelle est queue-récursive et donc optimisée pour éviter les débordements de pile. (Certaines personnes pourraient voir la récursion et penser que la programmation fonctionnelle est mauvaise à cause de cela)
alternative
3
+1 pour décrire l'aspect le plus important de l'impératif vs fonctionnel: flux de contrôle vs flux de données. Une chose que je dois ajouter est que le paradigme fonctionnel et le paradigme OO ne s'excluent pas mutuellement; vous pouvez utiliser le paradigme OO pour modéliser la manière dont l'objet (données) interagit, et le paradigme fonctionnel pour transformer (manipuler) cet objet.
Lie Ryan
1
Fait intéressant, vous pouvez modéliser les données en tant que contrôle et contrôle en tant que données pour les mélanger. FP peut utiliser les flèches et les fonctions de premier ordre pour transmettre le flux de contrôle et le manipuler comme des données. OOP utilise divers modèles de conception pour utiliser des objets afin de modifier le flux de contrôle.
CodexArcanum
Je pense qu’il est également intéressant de noter que la différence principale n’est pas que vous écriviez le même programme mais que vous utilisiez vos appels de méthode récursive en boucle. c'est beaucoup plus grand que ça
sara
Votre exemple fonctionnel utilise la correspondance de modèle de paramètre. Cela n’est pas exclusif à la programmation fonctionnelle. De même, les programmes fonctionnels peuvent utiliser des monades et même des constructions de type impératif sans nécessairement avoir à formuler chaque algorithme itératif en tant qu’algorithme récursif.
Dai
16

La programmation fonctionnelle est basée sur un modèle déclaratif et tire ses racines du lambda calcul. Il propose de nombreux concepts intéressants qui peuvent être empruntés à des langages plus impératifs tels que C ++ et C #.

Certains exemples incluent la transparence référentielle, les fonctions lambda, les fonctions de première classe, l’évaluation paresseuse et avide et l’immutabilité.

Si pour rien d'autre, apprendre la programmation fonctionnelle est utile pour les concepts qu'il contient. Cela changera votre façon de programmer et de penser à la programmation. Et je suppose qu’à l’avenir, la programmation fonctionnelle sera aussi importante que la programmation orientée objet.

Pour commencer, vous pouvez choisir d'utiliser un langage purement fonctionnel tel que Haskell, ou un langage hybride tel que F # .

La plupart des bonnes universités couvriront la programmation fonctionnelle et si vous allez à l'école, je vous suggère fortement de suivre ce cours.


Quelles sont les grandes différences, avantages et inconvénients de la programmation fonctionnelle par rapport à la programmation orientée objet?

Une bonne programmation orientée objet est intéressante car elle vous permet de modéliser votre problème complexe en hiérarchies afin de simplifier le problème. Mais cela devient très difficile lorsque vous commencez à envisager une programmation multithread tout en utilisant des objets mutables. Dans de tels cas, vous devez utiliser fréquemment des objets de synchronisation et il est pratiquement impossible de mettre au point une application volumineuse.

C'est là qu'intervient la programmation fonctionnelle. En raison de choses comme l'immutabilité, la programmation fonctionnelle simplifie vraiment les programmes multithreads. Il est presque trivialement facile de paralléliser quelque chose quand on sait que si on donne l’entrée X à une fonction, elle sera toujours sortie Y. Vous savez également qu’une variable (ou une valeur dans la programmation fonctionnelle) ne peut pas changer d’utilisation en cours à partir d’un autre thread.

Brian R. Bondy
la source
2
Pour être clair, Scheme n’est en aucun cas un pur langage fonctionnel.
Jonathan Sterling
5
Votre deuxième dernier paragraphe est complètement bs. OO ne pose aucun problème en multithreading, la mutabilité en est un. Vous semblez confondre programmation impérative et programmation orientée objet. Est-ce le cas?
missingfaktor
5
@missingfaktor: Non, je ne confonds pas les concepts. Un objet a généralement des accesseurs, des modificateurs, des membres de données et des fonctions de membre. Oui, tous les objets n'ont pas besoin de modificateurs et vous pouvez les implémenter comme étant immuables. Mais si vous regardez n'importe quel programme OO arbitraire, il aura presque certainement plusieurs objets qui ont des modificateurs et qui sont toujours utilisés par les multi-threads. Dans un paradigme de POO, il est assez rare que tout soit immuable.
Brian R. Bondy
Vous devriez lire les réponses à cette question: stackoverflow.com/questions/3949618/fp-and-oo-orthogonal/…
missingfaktor
Consultez également la réponse de Frank Shearar ici: programmers.stackexchange.com/questions/12423/…
missingfaktor
8

(Cette réponse est adaptée d'une réponse à une question fermée de StackOverflow .)

L'une des grandes différences entre la programmation fonctionnelle et la programmation orientée objet réside dans le fait que chacune d'elles est meilleure dans un type d'évolution logicielle différente:

  • Les langages orientés objet sont utiles lorsque vous avez un ensemble d' opérations fixes sur les choses , et à mesure 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 utiles lorsque vous avez un ensemble d' éléments fixe et que, à mesure que votre code évolue, vous ajoutez principalement de nouvelles opérations sur les é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.

Lorsque l'évolution va dans le mauvais sens, vous avez des problèmes:

  • L'ajout d'une nouvelle opération à un programme orienté objet peut nécessiter l'édition de nombreuses définitions de classe pour ajouter une nouvelle méthode.

  • L'ajout d'un nouveau type d'objet à un programme fonctionnel peut nécessiter l'édition de nombreuses définitions de fonctions pour ajouter un nouveau cas.

Ce problème est connu depuis de nombreuses années. En 1998, Phil Wadler l'a surnommé le "problème d'expression" . Bien que certains chercheurs pensent que le problème de l'expression peut être résolu avec des fonctionnalités de langage telles que mixins, une solution largement acceptée n'a pas encore été trouvée.

Norman Ramsey
la source
J'aime votre réponse, mot de sagesse ici. Je l'ai rencontré il y a quelques mois et je viens de passer 30 minutes à le rechercher, car je ne l'ai pas marqué. Juste la meilleure explication sur la POO vs la PF pour ceux qui comprennent l'avantage de comprendre les concepts plutôt que les techniques. L'article sur le problème de l'expression est également fantastique. Merci beaucoup de partager vos idées, votre réponse est très sous-estimée à mon avis.
tobiak777
4

Il n'y a pas de réel versus. Ils peuvent être parfaitement complémentaires. Il existe des langues de PF qui prennent en charge la POO. Mais les communautés diffèrent dans la manière dont elles gèrent la modularité.

Les utilisateurs de langages de PF ont tendance à atteindre la modularité grâce à des lois mathématiques. Et préférez les preuves pour montrer le respect de leurs lois.

En situation impérative, les utilisateurs de la programmation orientée objet ont tendance à capturer le comportement de l'objet dans des cas de test, ce qui peut être réexécuté si l'objet a changé, ce qui permet d'obtenir une modularité optimale.

C'est juste un petit aspect, mais je pense que cela mérite d'être mentionné.

Edgar Klerks
la source
2

Une analogie:

Vous êtes remis une demande d'emploi. Vous remplissez votre nom, vos coordonnées et votre historique de travail. Lorsque vous avez terminé, vous n'avez plus une application vierge.

Maintenant, imaginez plutôt qu'avant d'écrire, recouvrez-le d'une feuille de cellophane transparente. Tu écris ton nom. Vous ajoutez une autre feuille de cellophane. Vous écrivez vos informations de contact. Plus de cellophane. Vous écrivez votre histoire de travail. Lorsque vous avez terminé, la demande vierge est toujours intacte. Vous avez également trois feuilles de cellophane ayant chacune capturé l’effet d’un seul changement discret.

Le premier (OOP) embrasse l’idée de changer les choses en place alors que le second (FP) l’évite. Les deux sont des paradigmes de gestion d'État. Les deux stratégies peuvent, en utilisant différentes stratégies, capturer l’effet de remplir une demande d’emploi. La POO change directement l'instrument de départ, tandis que la FP recouvre ce qui était auparavant pour faire apparaître le changement .

Mario T. Lanza
la source
belle analogie, merci !! cela vous dérangerait-il (si possible) d’étendre cette analogie avec le pour et le contre dans ces deux approches.
Rahul Agarwal