Question

Software Engineering comme il est enseigné aujourd'hui est entièrement axée sur la programmation orientée objet et la vue orientée objet « naturel » du monde. Il y a une méthodologie détaillée qui décrit comment transformer un modèle de domaine dans un modèle de classe avec plusieurs étapes et beaucoup de (UML) des objets comme des cas d'utilisation diagrammes ou des diagrammes de classes. De nombreux programmeurs ont intériorisé cette approche et avoir une bonne idée sur la façon de concevoir une application orientée objet à partir de zéro.

Le nouveau battage médiatique est la programmation fonctionnelle, ce qui est enseigné dans de nombreux livres et des tutoriels. Mais qu'en est-génie logiciel fonctionnel? Alors que la lecture sur Lisp et Clojure, je suis tombé sur les deux déclarations intéressantes:

  1. programmes fonctionnels sont souvent développés en bas au lieu de haut en bas ( 'On Lisp', Paul Graham)

  2. Les programmeurs fonctionnels utilisent des cartes où OO-programmeurs utilisent des objets / classes ( 'Clojure pour les programmeurs Java', parler par Rich Hickley).

Alors, quelle est la méthodologie pour une conception systématique (basée sur un modèle?) D'une application fonctionnelle, à savoir dans Lisp ou Clojure? Quelles sont les étapes communes, ce que les artefacts dois-je utiliser, comment puis-je les mapper de l'espace de problème à l'espace de solution?

Était-ce utile?

La solution

Merci Dieu que le peuple génie logiciel ont pas encore découvert la programmation fonctionnelle. Voici quelques parallèles:

  • De nombreux OO "design patterns" sont capturés en tant que fonctions d'ordre supérieur. Par exemple, le modèle des visiteurs est connu dans le monde fonctionnel comme un « pli » (ou si vous êtes un théoricien-headed pointu, un « catamorphisme »). Dans les langages fonctionnels, types de données sont principalement des arbres ou des tuples, et chaque type d'arbre a un catamorphisme naturel associé.

    Ces fonctions d'ordre supérieur viennent souvent avec certaines lois de programmation, alias « théorèmes libres ».

  • programmeurs fonctionnels utilisent des schémas beaucoup moins lourd que les programmeurs OO. Une grande partie de ce qui est exprimé dans les diagrammes OO est la place exprimée dans types , ou « signatures », que vous devez penser comme « types de modules ». Haskell a aussi des "classes de type", qui est un peu comme un type d'interface.

    Les programmeurs fonctionnels qui utilisent des types pensent généralement que « une fois que vous obtenez les bons types,. Le code écrit pratiquement lui-même »

    Toutes les langues fonctionnelles utilisent des types explicites, mais le livre de Comment concevoir des programmes, un excellent livre pour l'apprentissage Scheme / Lisp / Clojure, repose en grande partie sur les "descriptions de données", qui sont étroitement liés à des types.

Alors, quelle est la méthodologie pour une conception systématique (basée sur un modèle?) D'une application fonctionnelle, à savoir dans Lisp ou Clojure?

Toute méthode de conception basée sur l'abstraction de données fonctionne bien. Je crois pour ma part que cela est plus facile quand la langue a des types explicites, mais il fonctionne même sans. Un bon livre sur les méthodes de conception pour les types de données abstraites, qui est facilement adapté à la programmation fonctionnelle, est Abstraction et spécification dans le développement du programme par Barbara Liskov et John Guttag, premier Edition . Liskov a remporté le prix Turing en partie pour ce travail.

Une autre méthode de conception qui est unique à Lisp est de décider ce que les extensions de langage seraient utiles dans le domaine du problème dans lequel vous travaillez, puis utiliser des macros hygiéniques pour ajouter ces constructions à votre langue. Un bon endroit pour lire ce genre de conception est l'article de Matthew Flatt Création des langues dans Racket . L'article peut être derrière un paywall. Vous pouvez également trouver du matériel plus général sur ce type de conception en recherchant le terme « langage intégré domaine spécifique »; des conseils et des exemples particulier au-delà de ce que couvre Matthew Flatt, je ne serais probablement commencer par Graham Sur Lisp ou peut-être ANSI Common Lisp .

Quelles sont les étapes communes, ce que les artefacts dois-je utiliser?

étapes communes:

  1. Identifier les données dans votre programme et les opérations sur, et définir un type de données abstrait représentant ces données.

  2. Identifier des actions communes ou les modes de calcul, et de les exprimer en tant que fonctions d'ordre supérieur ou des macros. Attendre à prendre cette étape dans le cadre de refactoring.

  3. Si vous utilisez un langage fonctionnel typé, utilisez le vérificateur de type tôt et souvent. Si vous utilisez Lisp ou Clojure, la meilleure pratique est de contrats de fonction d'écriture d'abord, y compris les tests-il unité de développement piloté par les tests au maximum. Et vous voulez utiliser quelle que soit la version de QuickCheck a été porté sur votre plate-forme, qui dans vos regards de cas comme on l'appelle ClojureCheck . Il est une bibliothèque extrêmement puissant pour construire des tests aléatoires de code qui utilise des fonctions d'ordre supérieur.

Autres conseils

Pour Clojure, je vous conseille de retourner à la bonne vieille modélisation relationnelle. Sur les Tarpit est une lecture inspirante.

Personnellement, je trouve que toutes les bonnes pratiques habituelles de développement OO appliquent dans la programmation fonctionnelle aussi bien - juste avec quelques modifications mineures pour tenir compte de la vision du monde fonctionnelle. Du point de vue de la méthodologie, vous n'avez pas vraiment besoin de faire quoi que ce soit fondamentalement différent.

Mon expérience vient d'avoir déplacé de Java à Clojure au cours des dernières années.

Voici quelques exemples:

  • Comprendre votre domaine / modèle de données entreprise - tout aussi important que vous allez concevoir un modèle d'objet ou de créer une structure de données fonctionnelle avec des cartes imbriquées. D'une certaine façon, FP peut être plus facile, car il vous encourage à penser à modèle de données séparément des fonctions / processus, mais vous devez toujours faire les deux.

  • orientation service dans la conception - fonctionne en fait très bien d'un point de vue de FP, car un service typique est vraiment juste une fonction avec des effets secondaires. Je pense que le point de vue du développement logiciel « bottom up » épousait parfois dans le monde Lisp est en fait de bons principes de conception API orientées services sous une autre forme.

  • Test Driven Development - fonctionne bien dans les langues FP, en fait parfois même mieux parce que les fonctions pures se prêtent très bien à l'écriture de tests clairs et reproductibles sans qu'il soit nécessaire de mettre en place un environnement stateful . Vous pouvez également créer des tests séparés pour vérifier l'intégrité des données (par exemple, ne cette carte ont toutes les clés dans ce que je pense, d'équilibrer le fait que, dans un langage OO la définition de classe imposerait pour vous au moment de la compilation).

  • Prototying / itération - fonctionne aussi bien avec FP. Vous pourriez même être en mesure de prototype en temps réel avec les utilisateurs si vous obtenez très très bien à la création d'outils / DSL et de les utiliser au REPL.

OO programmation bien des données couples avec comportement. La programmation fonctionnelle sépare les deux. Donc, vous ne disposez pas des diagrammes de classes, mais vous avez des structures de données, et vous avez en particulier les types de données algébriques. Ces types peuvent être écrits pour correspondre très bien votre domaine, y compris l'élimination des valeurs impossibles par la construction.

Donc il n'y a pas des livres et des livres sur elle, mais il y a une à approche bien établie comme on dit, rendre les valeurs impossibles irreprésentable.

Ce faisant, vous pouvez faire une série de choix de représenter certains types de données que des fonctions au lieu, et inversement, ce qui représente certaines fonctions comme l'union des types de données à la place de sorte que vous pouvez obtenir, par exemple, la sérialisation, les spécifications plus strictes, optimisation, etc.

Alors, étant donné que, vous écrivez sur vos fonctions ADTS telles que vous établissez une sorte de algèbre - à savoir qu'il existe des lois fixes qui détiennent ces fonctions. Certains sont peut-être idempotent - même après plusieurs applications. Certains sont associatives. Certains sont transitif, etc.

Maintenant, vous avez un domaine sur lequel vous avez des fonctions qui composent selon des lois bien comportés. Un simple DSL intégré!

Oh, et des propriétés données, vous pouvez écrire des cours automatisée des tests randomisés d'entre eux (ala QuickCheck) .. et c'est juste le début.

Objet conception orientée n'est pas la même chose que le génie logiciel. Le génie logiciel a à voir avec l'ensemble du processus de la façon dont nous allons des exigences à un système de travail, à temps et avec un faible taux de défaut. La programmation fonctionnelle peut être différente de OO, mais il ne supprime pas les exigences, de haut niveau et des plans détaillés, la vérification et les tests, les mesures de logiciels, l'estimation, et tout ce que d'autres « trucs de génie logiciel ».

En outre, les programmes fonctionnels font la modularité d'exposition et d'une autre structure. Vos conceptions détaillées doivent être exprimées en termes de concepts dans cette structure.

Une approche est de créer un DSL interne dans le langage de programmation fonctionnelle de choix. alors le « modèle » est un ensemble de règles d'affaires exprimées dans la LIS.

Voir ma réponse à un autre message:

Comment Clojure de la séparation des préoccupations?

Je suis d'accord reste à écrire sur le sujet sur la façon de structurer les grandes applications qui utilisent une approche FP (plus il reste encore beaucoup à faire pour UIs Document conduit FP-)

Bien que cela puisse être considéré comme naïf et simpliste, je pense que « les recettes de conception » (une approche systématique de la résolution de problèmes appliqués à la programmation tel que préconisé par Felleisen et al. Dans leur livre HTDP ) serait proche de ce que vous semblez être à la recherche.

Ici, quelques liens:

http://www.northeastern.edu/magazine/0301/programming.html

http://citeseerx.ist.psu.edu/ viewdoc / résumé? doi = 10.1.1.86.8371

J'ai trouvé le comportement Driven Development pour un ajustement naturel pour le code qui se développe rapidement dans les deux Clojure et SBCL. L'avantage réel de tirer parti BDD avec un langage fonctionnel est que je tends à écrire beaucoup de tests unitaires de grain plus fin que je fais habituellement lors de l'utilisation des langues de procédure parce que je fais un meilleur travail de décomposer le problème en petits morceaux de fonctionnalité.

Je l'ai récemment trouvé ce livre: fonctionnelle et réactive Modélisation de domaine

Je pense est parfaitement conforme à votre question.

De la description du livre:

fonctionnelle et modélisation de domaine réactive vous apprend comment penser du modèle de domaine en termes de fonctions pures et comment les composer pour construire de plus grandes abstractions. Vous allez commencer par les bases de la programmation fonctionnelle et progresser graduellement aux concepts et modèles avancés que vous devez savoir pour mettre en œuvre des modèles complexes de domaine. Le livre montre comment les modèles avancés de FP comme types de données algébrique, la conception à base de, et l'isolement classe de types d'effets secondaires peuvent rendre votre Compose modèle pour la lisibilité et la vérifiabilité.

Honnêtement, si vous voulez des recettes de conception des programmes fonctionnels, jetez un oeil aux bibliothèques de fonctions standard telles que le Prélude de Haskell. En FP, les modèles sont généralement capturés par des procédures d'ordre supérieur (fonctions qui opèrent sur les fonctions) elles-mêmes. Donc, si un modèle est vu, souvent une fonction d'ordre supérieur est simplement créé pour capturer ce motif.

Un bon exemple est fmap. Cette fonction prend une fonction comme argument et l'applique à tous les « éléments » du second argument. Comme il fait partie de la classe de type Functor, une instance d'un Functor (par exemple une liste, graphique, etc ...) peut être passé comme second argument à cette fonction. Il saisit le comportement général de l'application d'une fonction à chaque élément de son second argument.

Il y a le style « calcul du programme » / « conception par le calcul » associé avec le professeur Richard Bird et l'algèbre du groupe de programmation à l'Université d'Oxford (Royaume-Uni), je ne pense pas qu'il soit trop exagéré de considérer cette méthodologie.

Personnellement, tandis que je aime le travail produit par le groupe AoP, je n'ai pas la discipline à la conception de la pratique de cette façon moi-même. Cependant que mon défaut, et non l'un de calcul du programme.

Eh bien,

En général beaucoup de langages de programmation fonctionnels sont utilisés dans les universités depuis longtemps pour « petits problèmes de jouets ».

Ils sont plus en plus populaires maintenant depuis POO a des difficultés avec la « programmation paralel » en raison de « l'état » .Et le style parfois fonctionnel est préférable pour le problème à portée de main comme Google MapReduce.

Je suis sûr que, quand les gars de functioanl frappé le mur [essayer de mettre en œuvre des systèmes plus grands que 1.000.000 lignes de code], certains d'entre eux viendra avec de nouvelles méthodologies d'ingénierie logicielle avec des mots buzz :-). Ils doivent répondre à la vieille question: Comment diviser le système en morceaux afin que nous puissions « mordre » chaque pièce une à la fois? [Travail itératif, en inceremental manière évolutive] à l'aide fonctionnel.

Il est certain que fonctionnel affectera notre Orienté Objet Style.We « encore » beaucoup de concepts de systèmes fonctionnels et adaptés à nos langues POO.

Mais seront des programmes fonctionnels seront utilisés pour un tel système? Vont-ils devenir courant principal? Telle est la question .

Et Personne ne peut venir avec une méthodologie réaliste sans mettre en œuvre un tel système, ce qui rend son-son sale mains. D'abord, vous devez faire votre sale mains suggèrent alors la solution. Solutions-Suggestions sans « douleurs réelles et la saleté » seront « fantaisie ».

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top