Tissage de code octet vs macros Lisp

11

J'ai lu sur les bibliothèques que les gens ont écrites pour des langages comme Java et C # qui utilisent le tissage de code octet pour faire des choses comme intercepter des appels de fonction, insérer du code de journalisation, etc. J'ai également lu des macros Lisp / Clojure dans un essayer de mieux comprendre comment les utiliser. Plus je lis sur les macros, plus il semble qu'elles fournissent le même type de fonctionnalités que les bibliothèques de tissage de code d'octets. Par fonctionnalité, j'entends la possibilité de manipuler du code au moment de la compilation.

Des exemples de bibliothèques que j'ai examinées seraient AspectJ, PostSharp et Cecil.

Peut-on faire quoi que ce soit avec l'un et pas avec l'autre? Résolvent-ils réellement les mêmes problèmes ou est-ce que je compare des pommes et des oranges?

mortalapeman
la source
2
le tissage de code d'octet est une solution de contournement lorsque vous avez besoin d'un langage dynamique mais que vous êtes coincé avec un langage typé
kevin cline
2
@kevincline essayez-vous sérieusement de lancer ce vieux combat?
Jonathan Henson

Réponses:

10

Le tissage de code octet et les macros sont deux choses différentes.

Le tissage de code octet est un moyen d'intercepter les appels de fonction, de sorte que vous pouvez injecter une sorte de fonctionnalité (généralement une préoccupation transversale comme la journalisation) dans un appel de fonction, avant ou après l'exécution de la fonction. Le tissage de code d'octet se fait au niveau du code d'octet, ce qui signifie qu'il se produit après la compilation. La fonction elle-même n'est pas affectée. C'est l'une des techniques utilisées par la programmation orientée aspect .

Les macros sont un moyen d'étendre la syntaxe d'une langue. Dans sa forme la plus simple, une macro est tout simplement un moyen d'enregistrer des séquences de touches, puis de les lire à l'aide d'une touche de raccourci. Les macros de langue fonctionnent de manière similaire; un mot clé ou une autre construction de syntaxe remplace une sorte d'extension de macro. Bien sûr, cela est trop simplifié; un meilleur exemple d'une macro spécifique à Lisp peut être trouvé ici .

Robert Harvey
la source
+1 pour avoir mentionné qu'il s'agit d'un moyen clé de mise en œuvre de l'AOP.
Jonathan Henson
Et les transactions ... n'oublions pas les transactions.
Jonathan Henson
3
Les macros LISP ne ressemblent en rien à «un moyen d'enregistrer les frappes».
kevin cline
1
Eh bien, certains concepts fondamentaux manquent à la réponse de l'OMI, ceux-ci pourraient être: AST, réflexion, métacircularité.
AndreasScheinert
2
@AndreasScheinert: L'OP n'a posé aucune question à ce sujet. Ce n'est pas une thèse; c'est juste une réponse à la question du PO.
Robert Harvey
5

Bien qu'elles puissent être utilisées dans le même but, les macros LISP sont assez différentes des plugins de tissage de code octet Java. Les macros LISP étendent la syntaxe LISP au niveau du code source LISP. Étant donné que les macros LISP sont écrites au même niveau que les autres codes LISP, elles constituent une fonctionnalité de langage couramment utilisée.

Les plugins de tissage de code octet Java fonctionnent au niveau de la machine virtuelle Java. Alors que de nombreux programmeurs Java peuvent utiliser des plugins de tissage de code octet écrits par d'autres, très peu de programmeurs Java écrivent leurs propres plugins de tissage de code octet.

Une partie du travail effectué par les plugins du compilateur Java se fait très facilement dans des langages dynamiques. L'interception d'appels de fonction est particulièrement simple.

Kevin Cline
la source
Je comprends les différences techniques entre les deux. J'essayais d'examiner la question d'un point de vue élevé. Les deux outils peuvent-ils manipuler le code pour atteindre les mêmes objectifs? Y a-t-il des problèmes que les macros ne peuvent pas résoudre que la manipulation de bytecode peut (d'une manière saine et rentable)? C'est plus ce que j'allais chercher.
mortalapeman
@mortalapeman: les manipulations possibles en Java et C # via la modification de code octet peuvent toutes se faire directement dans des langages comme Lisp, Ruby, Python, Lua, Javascript ... Il est vraisemblablement possible de faire tout ce qu'une macro LISP peut faire via octet -manipulation de code, mais en pratique cela ne se produit pas.
kevin cline
4

Les macros Lisp fonctionnent au niveau du code source. Si vous enveloppez une macro autour d'un morceau de code, vous pouvez faire beaucoup de choses. Y compris l'analyse du code source, l'insertion de code, la réécriture de code, etc.

Si vous souhaitez modifier les appels de fonction, Lisp utilise généralement deux mécanismes:

  • symboles de liaison tardive. Vous pouvez modifier la fonction liée à un symbole. Chaque fonction appelant qui passe par un symbole, utilise alors la nouvelle fonction.

  • Les implémentations Lisp fournissent parfois une fonctionnalité appelée «conseil». Cela permet d'exécuter du code avant, après ou autour des appels. Par exemple dans LispWorks: Advice .

Ainsi, vous pouvez intercepter des appels sans manipulation de code de bas niveau.

Rainer Joswig
la source