Comment concevez-vous un programme fonctionnel?

Dès le premier jour de ma carrière en programmation, j’ai commencé avec la programmation orientée object. Cependant, je suis intéressé à apprendre d’autres paradigmes (ce que j’ai dit ici à plusieurs resockets est une bonne chose, mais je n’ai pas eu le temps de le faire). Je pense que je ne suis pas seulement prêt, mais j’ai le temps, alors je vais commencer la functional programming avec F #.

Cependant, je ne suis pas sûr de savoir comment structurer beaucoup moins d’applications de conception. Je suis habitué aux idées de classe-par-fichier et de classe-nom / fonction-verbe en programmation OO. Comment concevez-vous et structurez-vous des applications fonctionnelles?

Lisez le SICP .

De plus, une version PDF est disponible.

Vous voudrez peut-être consulter une entrée récente de mon blog: Comment la functional programming affecte-t-elle la structure de votre code?

À un niveau élevé, une méthodologie de conception OO est encore très utile pour structurer un programme F #, mais vous constaterez que cela s’est produit (plus d’exceptions à la règle) à mesure que vous descendez à des niveaux inférieurs. Au niveau physique, “une classe par fichier” ne fonctionnera pas dans tous les cas, car des types mutuellement récursifs doivent être définis dans le même fichier ( type Class1 = … et Class2 = …), et un peu de votre le code peut résider dans des fonctions “libres” non liées à une classe particulière (c’est à cela que servent les “modules” F #). Les contraintes de classement des fichiers dans F # vous obligeront également à réfléchir de manière critique aux dépendances entre les types de votre programme. c’est une arme à double tranchant, car cela peut nécessiter plus de travail / de reflection pour démêler les dépendances de haut niveau, mais aboutira à des programmes organisés de manière à toujours les rendre accessibles (les entités les plus primitives étant toujours les premières et vous pouvez toujours lire un programme de haut en bas et avoir de nouvelles choses introduites une par une, plutôt que de commencer à chercher un répertoire contenant des fichiers de code et ne pas savoir par où commencer ».

Comment concevoir des programmes est tout à propos de cela (longueur fastidieuse, en utilisant Scheme au lieu de F #, mais les principes sont reportés). En bref, votre code reflète vos types de données. cette idée remonte à l’ancienne “programmation structurée”, seule la functional programming est plus explicite à ce sujet et avec des types de données plus sophistiqués.

Étant donné que les langages fonctionnels modernes (c.-à-d. Non lisps) utilisent par défaut des fonctions polymorphes précoces (efficacement), et que l’orientation object n’est qu’une façon particulière d’avoir des fonctions polymorphes, elle n’est pas vraiment différente. concevoir des classes correctement encapsulées.

Les Lisps utilisent la liaison tardive pour obtenir un effet similaire. Pour être honnête, il n’y a pas beaucoup de différence, sauf que vous ne déclarez pas explicitement la structure des types.

Si vous avez beaucoup programmé avec les fonctions de modèle C ++, vous avez probablement déjà une idée.

Dans tous les cas, la réponse est petite “classes” et au lieu de modifier l’état interne, vous devez renvoyer une nouvelle version avec un état différent.

F # fournit les approches OO classiques pour la programmation structurée à grande échelle (par exemple, les interfaces) et ne tente pas de fournir les approches expérimentales mises au point dans des langages tels que OCaml (par exemple, les foncteurs).

Par conséquent, la structuration à grande échelle des programmes F # est essentiellement la même que celle des programmes C #.

La functional programming est un paradigme différent à coup sûr. La manière la plus simple de comprendre la situation est peut-être d’insister pour que la conception soit conçue à l’aide d’un organigramme. Chaque fonction est distincte, aucun inheritance, aucun polymorphism, distinct. Les données sont transmises d’une fonction à l’autre pour effectuer des suppressions, des mises à jour, des insertions et créer de nouvelles données.

Sur les programmes fonctionnels structurants:

Alors que les langages OO structurent le code avec les classes, les langages fonctionnels le structurent avec des modules. Les objects contiennent des états et des méthodes, les modules contiennent des types de données et des fonctions. Dans les deux cas, les unités structurelles regroupent les types de données avec le comportement associé. Les deux paradigmes ont des outils pour construire et appliquer des barrières d’abstraction.

Je recommande vivement de choisir un langage de programmation fonctionnel avec lequel vous êtes à l’aise (F #, OCaml, Haskell ou Scheme) et d’examiner de manière approfondie la structure de sa bibliothèque standard.

Comparez, par exemple, le module OCaml Stack avec System.Collections.Generic.Stack à partir de .NET ou une collection similaire en Java.

Il s’agit de fonctions pures et de la façon de les composer pour créer de plus grandes abstractions. C’est en fait un problème difficile pour lequel un contexte mathématique robuste est nécessaire. Heureusement, il existe plusieurs modèles avec des recherches formelles et pratiques approfondies. Sur la modélisation fonctionnelle et réactive des domaines, Debasish Ghosh explore ce sujet et rassemble plusieurs scénarios pratiques appliquant des modèles fonctionnels purs:

La modélisation fonctionnelle et réactive des domaines vous apprend à concevoir le modèle de domaine en termes de fonctions pures et à les composer pour créer de plus grandes abstractions. Vous commencerez par les bases de la functional programming et progresserez progressivement vers les concepts et modèles avancés que vous devez connaître pour implémenter des modèles de domaine complexes. Le livre montre comment des modèles de FP avancés tels que les types de données algébriques, la conception basée sur la classe de fonts et l’isolation des effets secondaires peuvent faire de votre modèle une source de lisibilité et de vérifiabilité.