Je suis développeur Web depuis un certain temps maintenant et j'ai récemment commencé à apprendre la programmation fonctionnelle. Comme d'autres, j'ai eu du mal à appliquer bon nombre de ces concepts à mon travail professionnel. Pour moi, la raison principale en est que je vois un conflit entre l'objectif de FP de rester apatride semble assez en contradiction avec le fait que la plupart des travaux de développement Web que j'ai effectués ont été fortement liés aux bases de données, qui sont très centrées sur les données.
Une chose qui a fait de moi un développeur beaucoup plus productif du côté de la POO a été la découverte de mappeurs relationnels objet comme MyGeneration d00dads pour .Net, Class :: DBI pour perl, ActiveRecord pour ruby, etc. Cela m'a permis de rester à l'écart de l'écriture, insérer et sélectionner des déclarations toute la journée, et se concentrer sur le travail avec les données facilement en tant qu'objets. Bien sûr, je pouvais toujours écrire des requêtes SQL lorsque leur puissance était nécessaire, mais sinon, c'était bien résumé dans les coulisses.
Maintenant, en ce qui concerne la programmation fonctionnelle, il semble que de nombreux frameworks Web FP tels que Links nécessitent l'écriture de beaucoup de code SQL standard, comme dans cet exemple . Weblocks semble un peu mieux, mais il semble utiliser une sorte de modèle POO pour travailler avec des données, et nécessite toujours que le code soit écrit manuellement pour chaque table de votre base de données comme dans cet exemple . Je suppose que vous utilisez une génération de code pour écrire ces fonctions de mappage, mais cela semble décidément non lisp.
(Notez que je n'ai pas regardé de très près Weblocks ou Links, je ne comprends peut-être pas comment ils sont utilisés).
La question est donc, pour les parties d'accès à la base de données (qui, à mon avis, sont assez volumineuses) d'une application Web, ou d'un autre développement nécessitant une interface avec une base de données SQL, nous semblons être obligés de suivre l'un des chemins suivants:
- N'utilisez pas de programmation fonctionnelle
- Accédez aux données d'une manière ennuyeuse et non abstraite qui implique l'écriture manuelle de beaucoup de code SQL ou de type SQL comme des liens
- Forcer notre langage fonctionnel dans un paradigme pseudo-POO, supprimant ainsi une partie de l'élégance et de la stabilité d'une véritable programmation fonctionnelle.
De toute évidence, aucune de ces options ne semble idéale. A trouvé un moyen de contourner ces problèmes? Y a-t-il vraiment un problème ici?
Remarque: Personnellement, je suis plus familier avec LISP sur le front FP, donc si vous voulez donner des exemples et connaître plusieurs langues FP, lisp serait probablement la langue préférée de choix
PS: Pour les problèmes spécifiques à d'autres aspects du développement Web, consultez cette question .
la source
Réponses:
Tout d'abord, je ne dirais pas que CLOS (Common Lisp Object System) est "pseudo-OO". C'est OO de première classe.
Deuxièmement, je crois que vous devriez utiliser le paradigme qui correspond à vos besoins.
Vous ne pouvez pas stocker de données sans état, alors qu'une fonction est un flux de données et n'a pas vraiment besoin d'état.
Si vous avez plusieurs besoins mélangés, mélangez vos paradigmes. Ne vous limitez pas à n'utiliser que le coin inférieur droit de votre boîte à outils.
la source
En venant à ceci du point de vue d'une personne de base de données, je trouve que les développeurs frontaux essaient trop dur de trouver des moyens d'adapter les bases de données à leur modèle plutôt que d'envisager les moyens les plus efficaces d'utiliser une base de données qui ne sont pas orientées objet ou fonctionnelles mais relationnelles et utilisant théorie des ensembles. J'ai vu que cela aboutissait généralement à un code peu performant. Et en outre, cela crée un code difficile à régler en termes de performances.
Lors de l'examen de l'accès à la base de données, il y a trois considérations principales: l'intégrité des données (pourquoi toutes les règles métier doivent être appliquées au niveau de la base de données et non via l'interface utilisateur), les performances et la sécurité. SQL est écrit pour gérer les deux premières considérations plus efficacement que n'importe quel langage frontal. Parce qu'il est spécifiquement conçu pour cela. La tâche d'une base de données est très différente de la tâche d'une interface utilisateur. Faut-il s'étonner que le type de code le plus efficace pour gérer la tâche soit conceptuellement différent?
Et les bases de données contiennent des informations essentielles à la survie d'une entreprise. Il n'est pas étonnant que les entreprises ne soient pas disposées à expérimenter de nouvelles méthodes lorsque leur survie est en jeu. Heck de nombreuses entreprises ne sont même pas disposées à passer à de nouvelles versions de leur base de données existante. Il existe donc un conservatisme inhérent à la conception de bases de données. Et c'est délibérément ainsi.
Je n'essaierais pas d'écrire T-SQL ou d'utiliser des concepts de conception de base de données pour créer votre interface utilisateur, pourquoi essayez-vous d'utiliser votre langage d'interface et vos concepts de conception pour accéder à ma base de données? Parce que vous pensez que SQL n'est pas assez sophistiqué (ou nouveau)? Ou vous ne vous sentez pas à l'aise avec ça? Ce n'est pas parce que quelque chose ne correspond pas au modèle avec lequel vous vous sentez le plus à l'aise que c'est mauvais ou faux. Cela signifie qu'il est différent et probablement différent pour une raison légitime. Vous utilisez un outil différent pour une tâche différente.
la source
Vous devriez regarder l'article «Out of the Tar Pit» de Ben Moseley et Peter Marks, disponible ici: «Out of the Tar Pit» (6 février 2006)
C'est un classique moderne qui détaille un paradigme / système de programmation appelé Programmation fonctionnelle-relationnelle. Bien que n'étant pas directement lié aux bases de données, il explique comment isoler les interactions avec le monde extérieur (bases de données, par exemple) du noyau fonctionnel d'un système.
Le papier discute également comment implémenter un système où l'état interne de l'application est défini et modifié en utilisant une algèbre relationnelle, qui est évidemment liée aux bases de données relationnelles.
Cet article ne donnera pas une réponse exacte sur la façon d'intégrer les bases de données et la programmation fonctionnelle, mais il vous aidera à concevoir un système pour minimiser le problème.
la source
Les langages fonctionnels n'ont pas pour but de rester apatrides, ils ont pour but de rendre explicite la gestion de l'état. Par exemple, dans Haskell, vous pouvez considérer la monade d'état comme le cœur de l'état «normal» et la monade IO une représentation d'état qui doit exister en dehors du programme. Ces deux monades vous permettent (a) de représenter explicitement des actions avec état et (b) de créer des actions avec état en les composant à l'aide d'outils référentiellement transparents.
Vous référencez un certain nombre d'ORM qui, par leur nom, résument les bases de données sous forme d'ensembles d'objets. Ce n'est vraiment pas ce que représentent les informations d'une base de données relationnelle! Par son nom, il représente des données relationnelles. SQL est une algèbre (langage) pour gérer les relations sur un ensemble de données relationnelles et est en fait assez "fonctionnel" lui-même. J'évoque cela afin de considérer que (a) les ORM ne sont pas le seul moyen de mapper les informations de base de données, (b) que SQL est en fait un langage assez sympa pour certaines conceptions de bases de données, et (c) que les langages fonctionnels ont souvent une algèbre relationnelle des mappages qui exposent la puissance de SQL de manière idiomatique (et dans le cas de Haskell, avec une vérification de type).
Je dirais que la plupart des lisps sont le langage fonctionnel d'un pauvre. Il est parfaitement capable d'être utilisé selon les pratiques fonctionnelles modernes, mais comme il ne les nécessite pas, la communauté est moins susceptible de les utiliser. Cela conduit à un mélange de méthodes qui peuvent être très utiles mais qui obscurcit certainement la façon dont les interfaces fonctionnelles pures peuvent toujours utiliser les bases de données de manière significative.
la source
Je ne pense pas que la nature sans état des langages fp soit un problème de connexion aux bases de données. Lisp est un langage de programmation fonctionnel non pur, il ne devrait donc pas avoir de problème avec l'état. Et les langages de programmation fonctionnels purs comme Haskell ont des moyens de gérer les entrées et les sorties qui peuvent être appliqués à l'utilisation de bases de données.
D'après votre question, il semble que votre principal problème réside dans la recherche d'un bon moyen d'abstraire les données basées sur les enregistrements que vous récupérez de votre base de données dans quelque chose qui est lisp-y (lisp-ish?) Sans avoir à écrire beaucoup de SQL code. Cela ressemble plus à un problème avec les outils / bibliothèques qu'à un problème avec le paradigme du langage. Si vous voulez faire de la FP pure, peut-être que lisp n'est pas le bon langage pour vous. Common lisp semble plus sur l'intégration de bonnes idées de oo, fp et d'autres paradigmes que sur pure fp. Peut-être devriez-vous utiliser Erlang ou Haskell si vous voulez emprunter la voie FP pure.
Je pense que les idées «pseudo-oo» de lisp ont aussi leur mérite. Vous voudrez peut-être les essayer. S'ils ne correspondent pas à la manière dont vous souhaitez travailler avec vos données, vous pouvez essayer de créer une couche au-dessus de Weblocks qui vous permet de travailler avec vos données comme vous le souhaitez. Cela pourrait être plus facile que de tout écrire vous-même.
Avertissement: je ne suis pas un expert Lisp. Je m'intéresse principalement aux langages de programmation et j'ai joué avec Lisp / CLOS, Scheme, Erlang, Python et un peu de Ruby. Dans la vie de programmation quotidienne, je suis toujours obligé d'utiliser C #.
la source
Si votre base de données ne détruit pas les informations, alors vous pouvez travailler avec elle d'une manière fonctionnelle cohérente avec des valeurs de programmation "purement fonctionnelles" en travaillant dans les fonctions de la base de données entière comme valeur.
Si au temps T la base de données indique que "Bob aime Suzie", et que vous aviez une fonction likes qui acceptait une base de données et un liker, alors tant que vous pouvez récupérer la base de données au temps T vous avez un programme fonctionnel pur qui implique une base de données . par exemple
Pour ce faire, vous ne pouvez jamais jeter les informations que vous pourriez utiliser (ce qui signifie en pratique que vous ne pouvez pas jeter les informations), de sorte que vos besoins de stockage augmenteront de manière monotone. Mais vous pouvez commencer à travailler avec votre base de données comme une série linéaire de valeurs discrètes, où les valeurs suivantes sont liées aux précédentes par le biais de transactions.
C'est par exemple l' idée majeure de Datomic .
la source
Pas du tout. Il existe un genre de bases de données connues sous le nom de «bases de données fonctionnelles», dont Mnesia est peut-être l'exemple le plus accessible. Le principe de base est que la programmation fonctionnelle est déclarative, donc elle peut être optimisée. Vous pouvez implémenter une jointure à l'aide de List Comprehensions sur des collections persistantes et l'optimiseur de requêtes peut déterminer automatiquement comment implémenter l'accès au disque.
Mnesia est écrit en Erlang et il existe au moins un framework web ( Erlyweb ) disponible pour cette plateforme. Erlang est intrinsèquement parallèle à un modèle de threading sans partage, donc à certains égards, il se prête à des architectures évolutives.
la source
Une base de données est le moyen idéal pour suivre l'état d'une API sans état. Si vous vous abonnez à REST, votre objectif est d'écrire du code sans état qui interagit avec une banque de données (ou un autre backend) qui garde une trace des informations d'état de manière transparente afin que votre client n'ait pas à le faire.
L'idée d'un mappeur objet-relationnel, dans lequel vous importez un enregistrement de base de données en tant qu'objet puis le modifiez, est tout aussi applicable et utile à la programmation fonctionnelle qu'à la programmation orientée objet. La seule mise en garde est que la programmation fonctionnelle ne modifie pas l' objet en place, mais l'API de base de données peut vous permettre de modifier l' enregistrement en place. Le flux de contrôle de votre client ressemblerait à ceci:
La base de données mettra à jour l'enregistrement avec vos modifications. La programmation fonctionnelle pure peut interdire la réaffectation des variables dans le cadre de votre programme , mais votre API de base de données peut toujours autoriser les mises à jour sur place.
la source
Je suis plus à l'aise avec Haskell. Le framework Web Haskell le plus important (comparable à Rails et Django) est appelé Yesod. Il semble avoir un ORM multi-backend assez cool, sécurisé. Jetez un œil au chapitre Persistance dans leur livre.
la source
Les bases de données et la programmation fonctionnelle peuvent être fusionnées.
par exemple:
Clojure est un langage de programmation fonctionnel basé sur la théorie des bases de données relationnelles.
Remarque: dans la dernière spécification2, la spécification ressemble plus à RMDB. voir: wiki spec-alpha2: Schema-and-select
Je préconise: Construire un modèle de données relationnelles au-dessus de la carte de hachage pour obtenir une combinaison des avantages NoSQL et RMDB. Il s'agit en fait d'une implémentation inversée de posgtresql.
Duck Typing: Si cela ressemble à un canard et charlatan comme un canard, ce doit être un canard.
Si le modèle de données de clojure comme une RMDB, les installations de clojure comme une RMDB et la manipulation des données de clojure comme une RMDB, clojure doit être une RMDB.
Clojure est un langage de programmation fonctionnel basé sur la théorie des bases de données relationnelles
Tout est RMDB
Mettre en œuvre un modèle de données relationnel et une programmation basée sur hash-map (NoSQL)
la source