Я читал о библиотеках, написанных людьми для таких языков, как Java и C #, в которых используется переплетение байт-кода для таких вещей, как перехват вызовов функций, вставка кода регистрации и т. Д. Я также читал в макросах Lisp / Clojure в попытаться лучше понять, как их использовать. Чем больше я читаю о макросах, тем больше кажется, что они предоставляют ту же функциональность, что и библиотеки для создания байт-кода. Под функциональностью я подразумеваю способность манипулировать кодом во время компиляции.
Примерами библиотек, которые я просматривал, были AspectJ, PostSharp и Cecil.
Есть ли что-нибудь, что можно сделать с одним, а не с другим? Они действительно решают те же проблемы, или я сравниваю яблоки и апельсины?
lisp
clojure
macros
aspect-oriented
mortalapeman
источник
источник
Ответы:
Плетение байт-кода и макросы - это две разные вещи.
Переплетение байтового кода - это способ перехвата вызовов функций, так что вы можете внедрить какую-то функциональность (обычно сквозную задачу, такую как ведение журнала) в вызов функции, либо до, либо после выполнения функции. Переплетение байтового кода выполняется на уровне байтового кода, что означает, что это происходит после компиляции. На саму функцию это не влияет. Это один из методов, которые использует Аспектно-ориентированное программирование .
Макросы - это способ расширить синтаксис языка. В своей простейшей форме макрос - это просто способ записывать нажатия клавиш, а затем воспроизводить их с помощью горячих клавиш. Языковые макросы работают аналогичным образом; ключевое слово или другая синтаксическая конструкция заменяет некоторое расширение макроса. Это упрощенно, конечно; лучший пример макроса, специфичного для Lisp, можно найти здесь .
источник
Хотя они могут использоваться для одной и той же цели, макросы LISP сильно отличаются от плагинов для создания байт-кода Java. Макросы LISP расширяют синтаксис LISP на уровне исходного кода LISP. Поскольку макросы LISP пишутся на том же уровне, что и другой код LISP, они являются широко используемой языковой функцией.
Подключаемые модули Java для создания байт-кода работают на уровне JVM. Хотя многие Java-программисты могут использовать плагины для создания байт-кода, написанные другими, очень немногие Java-программисты пишут свои собственные плагины для создания байт-кода.
Часть работы, выполняемой плагинами компилятора Java, очень легко выполняется на динамических языках. Перехват вызова функции особенно прост.
источник
Макросы Lisp работают на уровне исходного кода. Если вы оберните какой-нибудь макрос вокруг фрагмента кода, то вы сможете сделать много вещей. Включая анализ исходного кода, вставку кода, переписывание кода и т. Д.
Если вы хотите изменить вызовы функций, Лисп обычно использует два механизма:
поздние обязательные символы. Вы можете изменить функцию, связанную с символом. Каждый вызов функции, который проходит через символ, затем использует новую функцию.
Реализации на Лиспе иногда предоставляют функцию под названием «совет». Это позволяет выполнять код до, после или вокруг вызовов. Например, в LispWorks: Совет .
Таким образом, вы можете перехватывать вызовы без низкоуровневой обработки кода.
источник