Введение

В аспектно-ориентированном и функциональном программировании, совет (advice) описывает класс функций, которые модифицируют другие функции во время их выполнения; это функция, метод или процедура, предназначенная для применения в определенной точке соединения (join point) программы.

Читаемость

Советы могут приводить к путанице, поскольку совет, примененный к функции, не виден пользователю, изучающему исходное определение функции. В таких случаях советы работают почти как COMEFROM – шуточная конструкция, добавленная в INTERCAL для пародирования "спагеттизации", возникающей при чрезмерном использовании операторов GOTO. Однако на практике такие проблемы встречаются редко. Разработчики и сопровождающие пакетов и модулей Lisp никогда не используют советы, поскольку нет никакой выгоды от применения советов к функциям, когда их исходные определения можно свободно переписать для включения необходимых возможностей. Советы полезны лишь тем, что позволяют пользователям, использующим производные версии, впоследствии изменять поведение по умолчанию без необходимости распространения этих изменений в исходный код основной реализации.

Реализация

Форма советов существовала в C с классами в конце 1970-х и начале 1980-х годов, а именно функции, называемые "вызов" и "возврат", определённые в классе, которые вызывались перед (соответственно, после) методами класса. Однако они были исключены из C++. Советы являются частью Common Lisp Object System (CLOS) в виде методов :before, :after и :around, которые объединяются с основным методом посредством "стандартного комбинирования методов". Реализации Common Lisp предоставляют функциональность советов (в дополнение к стандартному комбинированию методов для CLOS) в качестве расширений. LispWorks поддерживает консультирование функций, макросов и методов CLOS. EmacsLisp добавил код, связанный с советами, в версии 19.28, 1994 года.

История

Ниже приведено из обсуждения в списке рассылки aosd discuss. Паскаль Костанца предоставил следующее:

Термин "advice" (дополнение) восходит к термину "advising" (консультирование), введенному Уорреном Тейтельманом в его докторской диссертации в 1966 году. Вот цитата из главы 3 его диссертации:

"Advising" (консультирование) – это основное новшество в модели и в системе PILOT. "Advising" (консультирование) заключается во вставке новых процедур в любую или все точки входа или выхода конкретной процедуры (или класса процедур). Вставленные процедуры называются "advice procedures" (процедурами-дополнениями) или просто "advice" (дополнениями). Поскольку каждое дополнение само по себе является процедурой, у него есть свои входы и выходы. В частности, это означает, что выполнение дополнения может привести к полному обходу процедуры, которую оно изменяет, например, путем указания в качестве выхода из дополнения одного из выходов исходной процедуры; или дополнение может изменить существенные переменные и продолжить вычисление таким образом, чтобы исходная процедура была выполнена, но с измененными переменными. Наконец, дополнение может не изменять ход выполнения или вообще не влиять на исходную процедуру, например, оно может просто выполнять некоторые дополнительные вычисления, такие как вывод сообщения или запись истории. Поскольку дополнения могут быть условными, решение о том, что делать, может зависеть от результатов вычислений на данный момент. Главное преимущество "advising" (консультирования) заключается в том, что пользователю не нужно беспокоиться о деталях фактических изменений в его программе или о внутреннем представлении дополнений. Он может рассматривать процедуру, к которой применяется дополнение, как единое целое, как один блок, и вносить в него изменения, не заботясь о деталях этого блока. Это можно противопоставить редактированию, в котором программист должен учитывать внутреннюю структуру процедуры. "Advising" (консультирование) было реализовано в BBN Lisp, а затем в Interlisp Xerox PARC. Оно также было использовано в Flavors, первом объектно-ориентированном расширении Lisp, разработанном в MIT. Эти возможности были объединены под понятием комбинации методов. Поскольку комбинация методов и макросы тесно связаны, также интересно отметить, что первая макросистема была описана в 1963 году, за три года до докторской диссертации Уоррена Тейтельмана.