|
|
Présentation du site Cours Erlang Articles Projets Autour d'Erlang-fr Liens English Area Miroir: Documentation Erlang Miroir: Archives Erlang/OTP Recherche ![]()
|
Programmation fonctionnelle et XMLBijan Parsia Cet article est traduit de l'anglais par Mickaël Rémond. L'article original est publié sur le site XML.com. Comme il est trop souvent coutume dans le monde de la programmation, la plupart de la communauté XML s'est identifiée et a mené ses travaux avec des langages de développement orientés objets (OOP). Bien qu'étant un fan de la programmation orientée objet, il est clair pour moi que même les meilleures techniques de développement orientées objet pour XML ne sont pas une panacée. Il existe de plus beaucoup d'utilisations horribles des techniques objets, une «objectification» utilisé de manière ad hoc qui rend nos vies de développeur plus difficiles et nos programmes moins clairs. Cette focalisation a deux conséquences négatives: Elle limite les techniques et les outils que nous utilisons et restreint ainsi notre compréhension du domaine considéré. Par exemple, bien que les bibliothèques construites sur DOM (Document Object Model) ne satisfassent que peu de monde et n'inspirent pas vraiment les développeurs, son statut de standard a tendance à inhiber (mais heureusement pas annihiler) les recherches autour de modèles et de pratiques alternatives. Le débat semble tourner autour de la question de l'amélioration de DOM, laquelle se traduit le plus souvent par la quète d'un meilleur modèle objet. Concevoir un meilleur modèle objet serait effectivement une bonne chose, mais nous devons garder à l'esprit qu'XML n'est ni historiquement, ni nécessairement orienté objet. Penser différement nous conduit à attendre un niveau d'adéquation avec les techniques objets que l'on obtiendra jamais. Un remède face à cette myopie intellectuelle peut être trouvé dans la recherche et l'exploration. Dans cet article, je vous livre un guide de voyage pour accompagner le débutant dans les passionnantes et instructives contrées de la programmation fonctionnel avec XML. Pourquoi utiliser la programmation fonctionnelle ?Si vous êtes très impliqué dans les développements XML et que vous utilisez déjà une grande palette de techniques liées à ce méta-langage, il est fort probable que vous utilisiez déjà un peu de programmation fonctionnelle. XSLT est plus ou moins une récupération du langage de tranformation DSSSL avec une syntaxe XML. XSLT est un sous-ensemble de DSSSL, qui est lui-même un sous-ensemble purement fonctionnel du langage de développement Scheme (accompagné d'une importante bibliothèque d'outils spécifiques). De fait, il existe non seulement des liens historiques entre la programmation fonctionnelle et XML mais des outils aujourd'hui essentiels pour l'utilisation de XML utilise la programmation fonctionnelle. Cette relation n'est pas seulement accidentelle. XML est généralement déclaratif, tout comme les langages de développement fonctionnels. XML est un méta-langage -- un langage pour définir des langages. ML, un des langages fonctionnels les plus importants, est ainsi nommé en référence à l'abbréviation de «Méta-Langage». En général, les languages de programmation fonctionnels sont en effet excellents pour la définition de language et pour leur implémentation. D'autre part, il est naturel de se représenter les documents XML comme des structures d'arbre; les languages fonctionnelles offrent un ensemble de fonctionnalités très pratiques pour représenter et manipuler des arbres. Pour finir, l'utilisation d'un langage de haut niveau s'appuyant sur un découpage structurel par des balises, dans lequel on définit plutôt les fonctions logiques que les procédures de rendu, est parfaitement dans l'esprit des langages fonctionnels, dans lequel on décrit les traitements en termes mathématiques, plutôt qu'en des termes orientés machines (ou «recette»). Il n'est pas nécessaire de développer dans un langage fonctionnel trés
évolué pour tirer partie des techniques et du mode de
pensée de la programmation fonctionnelle. Par exemple, les langages de scripts
Python et Perl, aujourd'hui parmi les plus populaires, ont tous les deux
plusieurs fonctionnalités inspirées par la programmation fonctionnelle et
peuvent être utilisés comme base d'expérimentation sur les techniques de
développement fonctionnel. Pour Python, cela vaut la peine de voir le module
(Note: Je recommande le parcours du site http://lambda.weblogs.com pour les personnes intéressées par un ensemble de liens et de discussion pas trop complexe sur les langages fonctionnels.) Vue d'ensembleComme son nom le laisse supposer, la programmation fonctionnelle est une approche du développement axée sur l'utilisation de «fonctions». Les langages fonctionnels offrent un ensemble exhaustif de manipulations applicables aux fonctions: Construire des fonctions, les combiner, les transmettre en paramètre à d'autres fonctions, les stocker dans des structures de données, etc. Cette utilisation des fonctions rend les langages fonctionnels (du moins en théorie) sans effet de bord. Le caractère déclaratif des langages fonctionnels facilite la mise au point de traitement parallèle (concurrence), la transformation de structures de données et la programmation d'outils de vérification, de validation et d'analyse. Les fonctions sont aux langages fonctionnels ce que les objects sont aux langages de développement orientés objets. Bien qu'il existe de nombreuses approches pour dresser la classification des langages fonctionnels, en particulier en s'appuyant sur des fonctionnalités techniques ou des propriétés formelles, une telle distinction n'est surtout utile qu'aux développeurs «fonctionnels» expérimentés. Une telle distinction est surtout perçue uniquement comme du jargon par les novices. J'ai plutôt une approche grossière mais opérationnelle pour classifier les langages fonctionnels. Mon approche permet de donner un aperçu de la philosophie de chaque langage au programmeur occasionnel dans un langage fonctionnel:
Malgré mon espoir de ne trouver par les lecteurs du site XML.com aucun membres de la communauté des langages fonctionnels -- ne serait-ce que pour mon ambition de jouer le rôle de guide -- je reconnais volontier que ce n'est pas une hypothèse réaliste. Donc, laisser moi anticiper les commentaires habituellement vicieux des groupes de discussion pour souligner certains points: Mercury est très obsédé par le typage; Beaucoup de ces langages s'appuient sur plusieurs paradigmes; et Common Lisp a énormément de fonctionnalités intéressantes. Pour le reste, considérer moi comme un guide tourisitique et non comme un «gourou». Je pourrais trouver des critères de distinction spécifiques pour toutes ces catégories de langages. Par exemple, les langages «lispiens» sont non typés, issus du lambda calcul, alors que les langages obsédés par les types s'appuie sur des variations typées. Cependant, j'ai essentiellement utilisé mon impression à l'égard de la «philosophie» de ces langages (NDT: look and feel) pour établir cette classification. Ainsi, Rebol n'utilise pas la syntaxe habituelle des expressions symboliques, ne ressemble donc pas à Lisp et rend impossible ou difficile l'utilisation de modèle de code classique en Lisp. Pourtant, lorsque je programme en Rebol, je me retrouve plutôt en train de penser comme si j'utilisais un système Scheme. Par conséquent, si vous maitriser un langage d'une catégorie, les autres sont peu susceptible de vous dérouter totalement. Un autre aspect important de la programmation fonctionnelle est qu'elle est l'objet d'un grand nombre de recherches universitaires, à un point tel qu'en général on l'écarte souvent de travaux industriels car on la considère uniquement comme un outil expérimental. En réalité, il existe plusieurs implémentations supportées commercialement de langages fonctionnels. De même, bon nombre de compilateurs et d'environnements gratuits sont d'excellentes qualité. Pour finir, la programmation fonctionnelle est est utilisée dans des environnements de production, parfois pour réaliser des tâches critiques. A l'opposé, il existe un ensemble important d'environnements de développement fonctionnels adaptés pour l'apprentissage et idéal pour faire ses premiers pas sans investir beaucoup de temps, d'énergie et sans se casser la tête dans l'installation d'un outil complexe. La nature expérimentale et universitaire de la programmation fonctionnel est une grande force. Pendant la préparation de cet article, j'ai lu beaucoup d'articles, dont certains traitaient de systèmes (par exemple XMLambda) non encore terminés ou même publiés. Cependant, les idées sous-jacentes et leur manière d'aborder le problème a considérablement enrichit ma manière de concevoir les traitements XML. Comme je l'ai mentionné plus haut, ce n'est pas seulement un manque d'outils qu'il nous faut résoudre. Nous devons nous abstraire des contraintes qui pèsent sur notre façon d'approcher la problèmatique d'XML. La suite de cet article met en avant les caractéristiques intéressantes de trois systèmes fonctionnels pour traiter des documents XML: XMLambda (Un langage fonctionnel spécifique aux traitements XML), HaXML (des fonctionnalités XML pour Haskell) et le nouveau module XML pour Erlang. XMLambdaXMLambda est un langage dédié pour traiter des documents XML qui est issu de la communauté des développeurs fonctionnels (ou plutôt, une définition de langage, car il n'est pas encore publié). Les autres exemples notables rassemble par exemple XDuce and divers langages de requète. En particulier, XMLamba est un langage optimisé pour la composition de documents XML «dynamiques», c'est-à-dire de documents dont certaines parties sont calculées et non pas saisies. Un élément intéressant d'XMLambda est qu'il est essentiellement le résultat de la question suivante: «A quoi ressemblerait un langage fonctionnel, obsédé par le typage, où un document XML serait tout simplement un programme ?». Cela signifie qu'un développeur XML minimaliste et pragmatique peut déjà écrire des programmes en XMLamba qui ressemblerait à:
Il est important d'admettre qu'il s'agit d'un programme assez complexe en XMLambda et pas simplement une chaine de caractères. Chaque élément est une construction du programme et un type lui est associé. Valider le XML est consiste simplement à compiler le programme. Comparez cela, l'espace d'un instant, avec les différents langages de scripts que l'on peut inclure dans des documents, comme par exemple JSP ou ASP. Dans la plupart de ces systèmes, le XML qui entoure le code et simplement du texte, que celui-ci représente des balises ou du contenu. Sémantiquement parlant, vous pourriez remplacer ce texte par une série d'instructions d'écriture (ou par une seule énorme, ou par des concaténations). Un aspect encore plus important et que les instructions d'écriture ne sont pas obligé de respecter, par exemple, les limites de balise. Il serait ainsi légitime d'écrire quelque chose comme:
Dans le cas dégénéré d'un document XML pure, le compilateur XMLambda est simplement un parseur XML validant, et nous en avons déjà un grand nombre. Cependant, parce que la validation opérée par XMLambda et finalement un élément d'un système de vérification de type plus général, même les documents-modèles (NDT: "templates") avec des traitements peuvent être «validés»:
Si j'avais déclaré La solution traditionnelle consiste à utiliser une représentation objet des éléments, ou bien d'appeler des procédures de génération des éléments pour fournir un vision unifiée, plus abstraite, du document dynamique. Cette approche fonctionne et vous pouvez même bâtir au-dessus un mode de validation (par exemple, faire en sorte que les noeuds vérifient la classe de leur enfants, etc). Cependant, cette façon de faire est monstrueusement maladroite, essentiellement parce que elle vous force à utiliser un trop haut niveau d'abstraction, sans parler de la notation encombrante. XMLambda vous permet de restez centré sur l'approche XML tout en fournissant un moyen cohérent et tout à fait naturel de construire des documents dynamiques complexes. HaXMLComme XMLambda, les outils de la bibliothèque HaXML traitent une DTD comme une série de déclarations de type dans un langage fonctionnel, permettant ainsi de réunir la validation et la vérification de typage. Dans l'approche d'HaXML, le langage utilisé est Haskell, un langage fonctionnel généraliste avec des fonctionnalités intéressantes et de nombreuses implémentations. Il manque à HaXML le caractère XML-centrique d'XMLambda. Cependant, les bibliothèques de mapping de HaXML permettent de travailler facilement et de manière cohérente avec des données XML et de manier les documents grâce à un langage de développement complet supportant une notation économique et pertinente. Une assertion intéressante que j'ai vu dans la littérature est que malgré le caractère très expressif du système de typage de Haskell de base (en particulier comparé au C, C++ ou au système de typage de Java) il se révèle soit insuffisant soit juste difficile à manier pour les documents XML. C'est précisément cette insuffisance qui justifie la conception de langage spécifique au traitement de documents XML utilisant un système de typage spécial (comme par exemple, XMLambda et XDuce). Le système de typage d'Haskell est cependant bien compris, bien documenté et bien implémenté. Tous ces paramètres en font un outil idéal pour explorer des systèmes de typages plus complets pour XML. Les outils de la bibliothèque HaXML introduisent un autre mécanisme, typiquement fonctionnel pour manipuler du XML: Les «combinateurs». Les combinateurs, ou les fonctions d'ordre supérieur, sont utilisés pour construire des fonctions complexes à partir de fonctions plus simples. Elles sont d'«ordre supérieur» parce qu'elles prennent des fonctions comme argument et renvoient une fonction comme résultat. Conceptuellement, elles sont proches des «tubes» Unix dans le sens où elles vous permettent de construire des séquences de traitement très complexes en arrageant avec souplesse des outils extrêmement spécialisés. En fait, la bibliothèque HaXML définit le «combinateur» appelés «composition Irlandaise» (représenté par un "o") qui applique une fonction au résultat d'une autre (de la même manière que les tubes Unix «appliquent» un programme au résultat d'un autre). Il exsite cependant beaucoup d'autres combinateurs qui font des choses utiles, comme par exemple ajouter le résultat d'une fonction à une autre de différentes façons ou sélectionner des résultats généré par une autre fonction. Le fait marquant à propos des combinateurs et qu'ils sont justes des fonctions définis dans le langage fonctionnel utilisé. Ainsi, si vous vous apercevez que vous utiliser un certain motif (pattern), il est facile de l'abstraire pour en faire un nouveau combinateur. Ainsi, la plupart des combinateurs prédéfinis dans HaXML sont de telles abstractions.
Clarifions la manière dont les traitements s'effectuent avec HaXML. D'abord,
HaXML définit bon nombre de fonctions de filtrage élémentaires. Par exemple
Cette approche donne une impression de s'épanouir avec l'accumulation de nouveaux filtres. Chaque petite étape pourrait être réalisée grâce à des techniques nécessitant plus de code, privilégiant ainsi le jeu réduit des constructions du langage au prix d'une notation moisn économique. Cette approche n'est pas nécessaire car vous définissez toujours les nouvelles constructions du langage à l'aide de l'ensemble de filtre élémentaires prédéfinis. L'agébrique vous permet d'utiliser des dérivés pour vous représentez les équivalences, plutôt que d'essayer de conserver en tête l'ensemble du flux des traitements. Certains trouvent que la syntaxe de ces combinateurs, qui ne s'appuie pas sur XML dans sa formulation, constitue une bonne alternative aux transformations XSLT. Personnellement, je trouve que la tendance à l'XMLisation de tout mécanisme d'expression, en particulier pour le développeur final, constitue plutôt une régression. Après tout, les concepteurs d'XML ont surtout voulu éliminer les fonctionnalités exclusivement rédactionnelles de SGML. Les exemples qui suivent sont extraits du premier article sur les transformations XML ("Transforming XML"). Je ne promet pas que la sémantique est parfaitement conservée, pour plusieurs raisons et en particulier le besoin de décrire élégamment l'utilisation des combinateurs. Copier des éléments vers le résultat du traitement
Supprimer des élements
Changer les noms d'élément
En plus de l'écriture de tranformations directement à partir de ces combinateurs, ceux-ci constituent également une bonne manière de compiler les autre langages de transformation, de style et de requète (Voir par exemple Xtract, un langage de requète XML ressemblant à XPath). ErXMLErlang est généralement considéré comme le représentant de la programmation fonctionnel de l'ère post-industrielle. Né chez Ericsson, conçu pour développer d'énorme applications, tolérantes aux pannes et extrêmement parallèles et pour faire fonctionner des applications de télécommunication dont le fonctionnement est critique et ne tolère aucune faiblesse, Erlang est un langage fonctionnel opérationnel (bien qu'il soit l'objet d'études universitaires intéressantes). Erlang est un langage fort sympathique et agréable à prendre en main. En effet, programmer en Erlang ressemble beaucoup à la manière de programmer en Smalltalk (Bon d'accord, "en Python"): Base syntaxique extrêmement simple, typage dynamique et bibliothèques très complètes. Erlang hérite de beaucoup de caractéristiques sémantiques et syntaxique de la programmation fonctionnelle: fonctions d'ordre supérieur, transparence référenciel des fonctions, assignement unique des variables, pattern matching, etc. Il dispose d'un système de module très propre et très simple. Sa fonctionnalité hors pair est bien sûr sa manière de gérer concurrence des traitements et la parallélisation. En fait, beaucoup de défenseurs du langage Erlang sont enthousiastes concernant son mode de conception orienté processus (NDT: process oriented design). Lors de la sixième conférence internationale des utilisateurs d'Erlang (EUC2000), Ulf Wiger a présenté ce qui ressemble à l'outil canonique de traitement XML en Erlang, XMerl (Il y a aussi un parseur «jouet» rudimentaire et un binding pour la boîte à outils: Edinburgh LT XML). Bien qu'encore au stade de version beta, XMerl est néanmoins d'ores et déjà utilisable et a déjà été utilisé pour implémenter une base de données XML au dessus de Mnesia, la base de données distribué développée en Erlang. Voici trois bonne raison de commencer à jouer avec XMerl:
XMerl n'est pas tout à fait à niveau en ce qui concerne le respect des standards, comme le sont les principaux outils XML. Cependant en tant qu'élément d'une solution plus général en Erlang, il peut jouer un rôle important dans certaines niches. Territoires inexplorésIl est toujours possible d'aller plus loin dans le domaine de la programmation fonctionnelle, et même dans les domaines précis que je viens de survoler. Les idées provenant du monde de la programmation fonctionnelles se sont toujours diffusées progressivement dans les pratiques courantes, mais nous atteignons un point où beaucoup de techniques et d'outils sont maintenant prêts à être acceptée dans le milieu industriel. Par exemple, James Clark a récemment proposé Trex, un langage permettant de valider des documents XML, aussi bien en terme de structure que de typage des données. D'après ses propres mots: essentiellement le système de typage de XDuce avec une syntaxe XML et bon nombre de fonctionnalités supplémentaires (comme le support des attributs et des espaces de noms) nécessaires à l'implémentation d'un langage de validation structurel. Il est aujourd'hui évident que tant que James Clark est dans les parages, la plupart d'entre nous pourront avoir l'opportunité de tirer parti des innovations de la programmation fonctionnelle. Il reste cependant beaucoup à gagner dans une meilleure compréhension et maîtrise des techniques de programmation fonctionnelle. Même si les outils sont récupérés et popularisé en dehors du champ fonctionnel traditionnel, il reste le problème de leur compréhension. Bien maîtriser ces outils reposent souvent sur l'acquisition préalable des pratiques et des théories qui les ont engendrés. Une des plus sérieux lacunes dans le monde de la programmation fonctionnelle est la quantité de documentation de bonne qualité, mais pas trop complexes, en particulier pour permettre aux programmeurs expérimentés dans d'autres paradigmes (par exemple, les langages impératifs ou les langages orientés objet) de se mettre à niveau. La plupart du temps le jargon de la programmation fonctionnel semble étrange, car il reste dérivé de la terminologie logique et mathématique (Il y a en fait un fil de discussion sur ce sujet dans le groupe de discussion Usenet comp.lang.functional, avec le sujet: "A Plea for Plain Functional English and Syntax"). Bien que cette situation s'améliore sans cesse, il est important de reconnaitre qu'une profonde et complète maîtrise de la programmation fonctionnelle n'est pas trivial, même dans des conditions optimales. Fort heureusement, il n'est pas nécessaire de maîtriser complètement la programmation fonctionnel pour récolter les premiers fruits de son apprentissage. J'ai découvert, qu'au moins en ce qui concerne XML, un minimum de travail est suffisant pour parcourir un grand chemin. |
Pour tout commentaire: erlang@erlang-fr.org
Dernière modification: 2005-11-11 18:48:6