Est-ce que FP et OO sont orthogonaux?

Je l’ai entendu à maintes resockets, et j’essaie de comprendre et de valider l’idée que FP et OO sont orthogonaux.

Tout d’abord, que signifie que deux concepts soient orthogonaux?

La PF encourage l’immuabilité et la pureté autant que possible, tandis que OO semble construit pour l’état et la mutation – une version légèrement organisée de la programmation impérative? Je me rends compte que les objects peuvent être immuables, mais OO semble impliquer un état / changement pour moi.

Ils ressemblent à des contraires. Comment cela affecte-t-il leur orthogonalité?

Un langage comme Scala facilite les opérations OO et FP, cela affecte-t-il l’orthogonalité des deux méthodes?

L’orthogonalité implique que deux choses ne sont pas liées. Cela vient des mathématiques où cela signifie perpendiculaire . Dans l’usage courant, cela peut signifier que deux décisions ne sont pas liées ou qu’un sujet n’est pas pertinent lorsqu’on considère un autre sujet. Tel qu’utilisé ici, orthogonal signifie qu’un concept n’implique ni n’exclut l’autre.

Les deux concepts de programmation orientée object et de functional programming ne sont pas incompatibles. L’orientation d’object n’implique pas la mutabilité. Beaucoup de gens qui sont initiés aux programmes orientés object de la manière traditionnelle utilisent souvent en premier lieu C ++, Java, C # ou des langages similaires où la mutabilité est courante et même encouragée (les bibliothèques standard offrent une variété de classes modifiables). Par conséquent, il est compréhensible que beaucoup de personnes associent la programmation orientée object à la programmation impérative et à la mutabilité, car c’est ainsi qu’ils l’ont appris.

Cependant, la programmation orientée object couvre des sujets tels que:

  • Encapsulation
  • Polymorphisme
  • Abstraction

Rien de tout cela n’implique la mutabilité, et rien n’exclut la functional programming. Alors oui, ils sont orthogonaux en ce qu’ils sont des concepts différents. Ils ne sont pas opposés – vous pouvez utiliser l’un ou l’autre ou les deux (ou même aucun). Des langages comme Scala et F # tentent de combiner les deux paradigmes dans un seul langage:

Scala est un langage de programmation multi-paradigmes conçu pour intégrer des fonctionnalités de programmation orientée object et de functional programming .

La source

F # est un langage fonctionnel et orienté object , concis, expressif et efficace pour .NET qui vous aide à écrire du code simple pour résoudre des problèmes complexes.

La source

Tout d’abord, que signifie que deux concepts soient orthogonaux?

Cela signifie que les deux concepts n’ont pas d’idées contrastées ou ne sont pas incompatibles les uns avec les autres.

La PF encourage l’immuabilité et la pureté autant que possible. et OO semble être quelque chose qui est construit pour l’état et la mutation (une version légèrement organisée de la programmation impérative?). Et je réalise que les objects peuvent être immuables. Mais OO semble impliquer état / changement pour moi.

Ils ressemblent à des contraires. Comment cela affecte-t-il leur orthogonalité?

Un langage comme Scala facilite les opérations OO et FP, cela affecte-t-il l’orthogonalité des deux méthodes?

OO concerne l’encapsulation, la composition des objects, l’abstraction des données, le polymorphism via le sous-typage et la mutation contrôlée si nécessaire (l’immuabilité est également encouragée dans OO). FP concerne la composition des fonctions, l’abstraction de contrôle et le polymorphism contraint (polymorphism paramésortingque). Les deux idées ne sont donc pas contradictoires. Ils vous offrent tous les deux différents types de pouvoirs et de mécanismes d’abstraction qu’il est certainement possible d’avoir dans une langue. En fait, c’est la thèse sur laquelle Scala a été construite!

Dans son exposé sur la Scala Experiment chez Google, Martin Odersky explique très bien comment, selon lui, les deux concepts – OO et FP – sont orthogonaux et comment Scala unifie les deux paradigmes avec élégance et transparence dans un nouveau paradigme connu dans la communauté Scala comme paradigme object-fonctionnel. Doit regarder parler pour vous. 🙂


Autres exemples de langages fonctionnels: OCaml , F # , Nemerle .

Tout d’abord, que signifie que deux concepts soient orthogonaux?

Cela signifie qu’ils ne s’affectent pas. C’est-à-dire qu’un langage fonctionnel n’est pas moins fonctionnel car il est également orienté object.

Ils ressemblent à des contraires. Comment cela affecte-t-il leur orthogonalité?

S’ils étaient opposés (c’est-à-dire qu’un langage purement fonctionnel ne pouvait pas être orienté object), ils ne seraient pas, par définition, orthogonaux. Cependant, je ne crois pas que ce soit le cas.

et OO semble être quelque chose qui est construit pour l’état et la mutation (une version légèrement organisée de la programmation impérative?). Et je réalise que les objects peuvent être immuables. Mais OO semble impliquer état / changement pour moi.

Bien que cela soit vrai pour la plupart des langages OO traditionnels, il n’ya aucune raison pour qu’un langage OO ait un état mutable.

Si un langage possède des objects, des méthodes, un inheritance virtuel et un polymorphism ad hoc, il s’agit d’un langage orienté object – qu’il ait ou non un état mutable.

Pour que deux concepts soient orthogonaux, ils peuvent être réalisés indépendamment à n’importe quel degré dans une manifestation donnée. En ce qui concerne la musique, par exemple, vous pouvez classer une pièce musicale en fonction de son harmonie et de son rythme. Les deux concepts “harmonique” et “rythmique” sont orthogonaux en ce sens qu’il existe des pièces harmoniques et rythmiques, des pièces disharmoniques et arrythmiques, mais aussi des pièces disharmoniques et rythmiques ainsi que des pièces harmoniques et arythmiques.

Appliqué à la question originale, cela signifie qu’il existe des langages de programmation purement fonctionnels, non orientés object tels que Haskell, des langages purement orientés object, “non fonctionnels” tels qu’Eiffel, mais aussi des langages qui ne sont ni C ni des langages les deux comme Scala.

En termes simples, Scala étant orienté object, vous pouvez définir des structures de données (“classes” et “traits”) qui encapsulent les données avec les méthodes manipulant ces données, garantissant que les instances de ces structures (“objects”) sont toujours dans une état défini (contrat de l’object défini dans sa classe).

En revanche, Scala étant un langage fonctionnel, il privilégie l’état immuable sur l’état mutable et les fonctions sont des objects de première classe, qui peuvent être utilisés comme tout autre object en tant que variables locales, champs ou parameters pour d’autres fonctions. En plus de cela, presque tous les énoncés de Scala ont une valeur, ce qui vous encourage à utiliser un style de programmation fonctionnel.

En outre, l’orthogonalité de la programmation orientée object et de la functional programming dans Scala signifie que vous, en tant que programmeur, êtes libre de choisir n’importe quel mélange de ces deux concepts, selon vos besoins. Vous pouvez écrire vos programmes dans un style purement impératif, en utilisant uniquement des objects modifiables et en n’utilisant pas de fonctions comme objects. D’autre part, vous pouvez également écrire des programmes fonctionnels dans Scala sans utiliser aucune de ses fonctionnalités orientées object.

Scala ne nécessite pas que vous utilisiez un style ou un autre. Il vous permet de choisir le meilleur des deux mondes pour résoudre votre problème.

Comme toutes les classifications, la division des langages de programmation en fonctionnels, orientés object, procéduraux, etc. est fictive. Mais nous avons besoin de classifications, et dans les langages de programmation, nous classifions par un ensemble de caractéristiques linguistiques et par l’approche philosophique de ceux qui utilisent le langage (où le dernier est influencé par le premier).

Donc, parfois, les langages “orientés object” peuvent avoir du succès en adoptant les caractéristiques et les philosophies des langages de programmation “fonctionnels” et vice-versa. Mais toutes les fonctionnalités et philosophies du langage de programmation ne sont certainement pas compatibles.

Par exemple, un langage fonctionnel tel que OCaml accomplit une encapsulation via la scope et les fermetures lexicales, tandis qu’un langage orienté object utilise des modificateurs d’access public / privé. Ce ne sont pas des mécanismes incompatibles en soi, mais ils sont redondants, et un langage comme F # (un langage surtout fonctionnel qui cherche à vivre en harmonie avec la bibliothèque et la stack de langages résolument orientée object) doit être long le trou.

Autre exemple, OCaml utilise un système de type structurel pour l’orientation de l’object, alors que la plupart des langages orientés object utilisent un système de type nominal. Celles-ci sont assez incompatibles et représentent une incompatibilité dans le domaine des langages orientés object.

L’idée des objects peut être mise en œuvre de manière immuable. Un exemple est le livre ” Une théorie des objects “, par Abadi et Cardelli, qui vise à formaliser ces idées, et où les objects reçoivent d’abord une sémantique immuable car cela rend le raisonnement sur les programmes orientés object plus simple.

Dans ce cas, une méthode qui aurait traditionnellement modifié l’object en place renvoie à la place un nouvel object, tandis que l’object précédent persiste.

Vous pouvez implémenter des fonctions en tant qu’objects et objects en tant que collections de fonctions. Il existe donc clairement une relation entre les deux concepts.

FP encourage l’immuabilité et la pureté autant que possible

Vous parlez de programmation purement fonctionnelle.

tandis que OO semble construit pour l’état et la mutation

Il n’y a aucune exigence que les objects soient mutables. Je dirais que les objects et les mutations sont des concepts orthogonaux. Par exemple, le langage de programmation OCaml fournit une syntaxe pour la mise à jour d’object purement fonctionnelle.

Un langage comme Scala, il est facile de faire OO et FP à la fois

Pas vraiment. L’absence d’optimisation des appels de queue signifie que la majorité des codes purement fonctionnels idiomatiques emstackront le débordement dans Scala car ils fuient les frameworks de stack. Par exemple, le style de passage continu (CPS) et toutes les techniques décrites dans l’étude That about s’enrichit de Bruce McAdam. Il n’y a pas de moyen facile de résoudre ce problème, car la JVM elle-même est incapable d’optimiser les appels de queue.

En ce qui concerne l’orthogonalité de la programmation purement fonctionnelle et de la programmation orientée object, je dirais qu’elles sont au moins presque orthogonales simplement parce que la programmation purement fonctionnelle ne concerne que les programmes de petite taille structuration à l’échelle des programmes. C’est pourquoi les langages de programmation fonctionnels fournissent généralement un autre mécanisme de structuration à grande échelle, par exemple les systèmes de modules de niveau supérieur standard ML et OCaml, ou les systèmes CLOS pour Common Lisp ou les classes de types pour Haskell.

Une chose qui m’a aidé à comprendre la relation entre FP et OO était le livre SICP, en particulier la section «Modularité des programmes fonctionnels et modularité des objects». Si vous réfléchissez à ces questions et que vous avez un week-end libre, les trois premiers chapitres, sa belle ouverture des yeux.

Je viens de trouver une explication merveilleuse de l’orthogonalité de la POO et de la PF.

L’idée basique est la suivante. Imaginez que nous travaillons avec des AST d’expressions mathématiques. Nous avons donc différents types de noms (constants, addition, multiplication) et différents verbes (eval, toSsortingng).

Disons que l’expression est (1 + 2) * 3 . Alors l’AST serait:

        multiplication
          / \
      addition 3
       / \
      1 2

Pour implémenter un verbe, nous devons fournir son implémentation pour chaque type de nom. Nous pouvons le représenter sous forme de tableau:

  +---------------------+-------------------------------------+ | eval | toSsortingng | +---------------+---------------------+-------------------------------------+ | constant | value | value.toSsortingng | +---------------+---------------------+-------------------------------------+ | addition | lhs.eval + rhs.eval | lhs.toSsortingng + " + " + rhs.toSsortingng | +---------------+---------------------+-------------------------------------+ | mutiplication | lhs.eval * rhs.eval | lhs.toSsortingng + " * " + rhs.toSsortingng | +---------------+---------------------+-------------------------------------+ 

L’orthogonalité vient du fait que, dans la POO, nous allons implémenter cette table par lignes : nous représenterons chaque nom comme une classe, qui devra implémenter chaque méthode.

Dans FP , par contre, nous allons implémenter cette table par colonnes – nous écrirons une fonction pour chaque verbe, et cette fonction réagira différemment aux arguments de différents types (en utilisant probablement une correspondance de modèle).

Orthogonal. Ça sonne bien. Si vous avez une éducation, vous pouvez la structurer et faire semblant. C’est un peu comme le paradigme.

Tout dépend des cercles dans lesquels vous voyagez et de ce que chaque type de technique de programmation vous donnera. J’ai lu quelques articles sur SS et la plupart de ceux qui viennent d’un langage de programmation fonctionnel persistent sur le fait que vous ne pouvez aller que fonctionnel et que tout le rest va à l’encontre de la pensée et de la mentalité.

La programmation orientée object consiste principalement à capturer l’état et à garder cet état aussi localisé que possible pour ne pas être affecté par quelque chose qui ne fait pas partie de l’object avec lequel vous gérez l’état. Par ailleurs, la functional programming examine le problème de l’état sous un angle différent et essaie de séparer l’état du système pour le réduire à des fonctions. Oui, vous pouvez utiliser les deux techniques dans votre code, mais tous deux étudient la conception de logiciels sous différents angles.

Les techniques de functional programming ont suscité un grand intérêt, principalement en raison de la gestion requirejse par l’état lorsqu’il s’agissait de puces multi-cœurs et de la programmation parallèle. Il semble à ce stade que la functional programming ait le dessus, mais vous pouvez obtenir le même effet en utilisant des objects. Vous pensez simplement au problème différemment. Au lieu de vous gratter la tête, en essayant de vous débarrasser autant que possible de l’état, vous regardez les objects dans la conception et voyez comment vous pouvez les associer à ce qu’ils sont censés faire, en utilisant des modèles de conception, CRC et Analyse d’objects Cependant, là où les objects entrent en jeu et où la functional programming est beaucoup plus difficile, c’est en analysant le monde réel et en le mappant avec un système informatique compréhensible. Dans OO par exemple, un object personne serait une encapsulation de l’état avec des méthodes qui agissent sur l’état des personnes. Dans la functional programming, une personne est décomposée en parties de données et fonctions qui agissent sur les données personnelles, à condition que les données soient créées une seule fois et soient immuables.

Je dois avouer que, dans un contexte OO, dans la plupart des langages OO, lorsque j’ai affaire à des puces multi-core, je suis passé principalement par des structures de programmation (threads et delegates) et des pseudo-objects de données. Cela m’a amené à remettre en cause les techniques de programmation OO car il ne semble pas bien mapper à ce design fileté.