En programmation fonctionnelle et aspect , un conseil décrit une classe de fonctions qui modifient d'autres fonctions lorsque ces dernières sont exécutées ; il s'agit d'une certaine fonction, méthode ou procédure qui doit être appliquée à un point de jonction donné d'un programme.
Utiliser
L'utilisation pratique des fonctions de conseil consiste généralement à modifier ou à étendre le comportement de fonctions qui ne peuvent ou ne devraient pas être facilement modifiées ou étendues. Par exemple, l' addon Emacspeak Emacs fait un usage intensif de conseils : il doit modifier des milliers de modules et de fonctions Emacs existants de manière à pouvoir produire une sortie audio pour les aveugles correspondant à la présentation visuelle, mais il serait impossible de les copier tous et de les redéfinir pour produire une sortie audio en plus de leurs sorties normales ; ainsi, les programmeurs d'Emacspeak définissent des fonctions de conseil qui s'exécutent avant et après.
Prenons un exemple simple d'Emacs : supposons qu'après qu'un utilisateur ait corrigé un mot mal orthographié en utilisant le module ispell d'Emacs , il veuille vérifier à nouveau l'orthographe de l'ensemble du tampon. ispell-wordn'offre pas une telle fonctionnalité, même si le mot corrigé apparaît fréquemment dans le tampon. L'utilisateur pourrait retrouver la définition de ispell-word, la copier dans ses fichiers Emacs personnels et y ajouter la fonctionnalité souhaitée, mais c'est fastidieux et, pire, fragile (la version de l'utilisateur n'est plus synchronisée avec l'implémentation principale d'Emacs, si elle fonctionne même sans refactorisation supplémentaire). Ce que l'utilisateur veut est assez simple : il suffit d'exécuter une autre commande à chaque ispell-wordexécution. En suivant les conseils, cela peut être fait aussi simplement que ceci :
( conseil-ajouter #' ispell-word :après #' flyspell-buffer )
Bien que cet exemple soit évidemment trivial, la force de advice, surtout lorsqu'on le compare à des outils similaires tels que les décorateurs Python et les annotations Java , réside dans le fait que non seulement les fonctions/méthodes conseillées n'ont pas besoin d'être conçues pour accepter des conseils, mais que les conseils eux-mêmes n'ont pas besoin d'être conçus pour être utilisables comme conseils - ce sont simplement des fonctions normales. La disponibilité de l'évaluation tout au long de la durée de vie d'un morceau de code (cf. code staging ) dans Lisp permet d' intégrer automatiquement advice dans n'importe quel autre code de diverses manières. N'importe quel morceau de code peut être conseillé d'effectuer n'importe quel autre calcul avant, après, autour ou à la place de sa définition d'origine.
Lisibilité
Les conseils peuvent être source de confusion, car un conseil appliqué à une fonction n'est pas apparent pour un utilisateur qui recherche la définition source de la fonction pour en savoir plus. Dans de tels cas, les conseils agissent presque comme un COMEFROM , une fonction de plaisanterie ajoutée à INTERCAL pour tromper la spaghettification qui accompagne l'utilisation intensive des GOTO . Dans la pratique, cependant, de tels problèmes se présentent rarement. Les développeurs et mainteneurs en amont de packages et de modules Lisp n'utilisent jamais les conseils, car il n'y a aucun avantage à conseiller les fonctions lorsque leurs définitions source originales peuvent être librement réécrites pour inclure les fonctionnalités souhaitées. Les conseils ne sont utiles que dans la mesure où ils permettent aux utilisateurs en aval de modifier ultérieurement le comportement par défaut d'une manière qui ne nécessite pas la propagation de ces modifications dans la définition source de l'implémentation principale.
Implémentations
Une forme de conseils faisait partie du langage C avec les classes à la fin des années 1970 et au début des années 1980, à savoir les fonctions appelées callet returndéfinies dans une classe, qui étaient appelées avant (respectivement, après) les fonctions membres de la classe. Cependant, ces conseils ont été abandonnés en C++ .
Les conseils font partie du système d'objets Common Lisp (CLOS), comme les méthodes :before, :after, et :around, qui sont combinées avec la méthode principale sous « combinaison de méthodes standard ».
Les implémentations Common Lisp fournissent des fonctionnalités de conseil (en plus de la combinaison de méthodes standard pour CLOS) sous forme d'extensions. LispWorks prend en charge les fonctions de conseil, les macros et les méthodes CLOS.
EmacsLisp a ajouté du code lié aux conseils dans la version 19.28, 1994.
Histoire
Ce qui suit est tiré d'une discussion sur la liste de diffusion aosd-discuss. Pascal Costanza y a contribué :
Le terme « conseil » remonte au terme advising introduit par Warren Teitelman dans sa thèse de doctorat en 1966. Voici une citation du chapitre 3 de sa thèse :
- Le conseil est l'innovation fondamentale du modèle et du système PILOT. Le conseil consiste à insérer de nouvelles procédures à un ou plusieurs points d'entrée ou de sortie d'une procédure particulière (ou d'une classe de procédures). Les procédures insérées sont appelées « procédures de conseil » ou simplement « conseils ».
- Comme chaque conseil est lui-même une procédure, il possède ses propres entrées et sorties. En particulier, cela signifie que l'exécution d'un conseil peut entraîner le contournement complet de la procédure qu'il modifie, par exemple en spécifiant comme sortie du conseil l'une des sorties de la procédure d'origine ; ou bien le conseil peut modifier des variables essentielles et poursuivre le calcul de sorte que la procédure d'origine soit exécutée, mais avec des variables modifiées. Enfin, le conseil peut ne pas modifier l'exécution ou affecter la procédure d'origine du tout, par exemple, il peut simplement effectuer un calcul supplémentaire tel que l'impression d'un message ou l'enregistrement d'un historique. Comme le conseil peut être conditionnel, la décision quant à ce qui doit être fait peut dépendre des résultats du calcul jusqu'à ce point.
- Le principal avantage de la fonction de conseil est que l'utilisateur n'a pas à se soucier des détails des changements réels dans son programme, ni de la représentation interne des conseils. Il peut traiter la procédure à conseiller comme une unité , un bloc unique, et y apporter des modifications sans se soucier des détails de ce bloc. Cela peut être contrasté avec l'édition dans laquelle le programmeur doit être conscient de la structure interne de la procédure.
Le terme « conseil » a trouvé sa place dans BBN Lisp et plus tard dans Interlisp de Xerox PARC .
Elle a également trouvé son chemin vers Flavors , la première extension orientée objet de Lisp développée au MIT . Elles ont été subsumées sous la notion de combinaison de méthodes.
Étant donné que la combinaison de méthodes et les macros sont étroitement liées, il est également intéressant de noter que le premier système de macros a été décrit en 1963, trois ans avant la thèse de doctorat de Warren Teitelman.