Content deleted Content added
Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0 |
|||
(21 intermediate revisions by 16 users not shown) | |||
Line 1:
In [[aspect-oriented programming|aspect]] and [[functional programming]], '''advice''' describes a class of [[Function (computer science)|functions]] which modify other functions when the latter are run; it is a certain function, method or procedure that is to be applied at a given [[join point]] of a program.
==Use==▼
The following is taken from a discussion at the mailing list [https://web.archive.org/web/20060513042952/http://aosd.net/pipermail/discuss_aosd.net/2004-November/001173.html aosd-discuss]. [[Pascal Costanza]] contributed the following:▼
The practical use of advice functions is generally to modify or otherwise extend the behavior of functions which cannot or should not be
The term '''advice''' goes back to the term ''advising'' as introduced by [[Warren Teitelman]] in his PhD thesis in 1966. Here is a quote from Chapter 3 of his thesis:▼
:Advising is the basic innovation in the model, and in the PILOT system. Advising consists of inserting new procedures at any or all of the entry or exit points to a particular procedure (or class of procedures). The procedures inserted are called "advice procedures" or simply "advice".▼
(advice-add #'ispell-word
</syntaxhighlight>
While this example is obviously trivial, the strength of advice, especially when compared to similar facilities such as [[Python_syntax_and_semantics#Decorators|Python decorators]] and [[Java annotations]], lies in the fact that not only do the advised functions / methods not need to be designed to accept advice, but also the advice themselves need not be designed to be usable as advice - they're just normal functions. The availability of [[eval|evaluation]] throughout the lifetime of a piece of code (cf. [[Multi-stage programming|code staging]]) in Lisp allows advice to be [[Inline expansion|inlined]] automatically into any other code in a variety of ways. Any piece of code can be advised to carry out any other computation before, after, around, or instead of its original definition.
:Since each piece of advice is itself a procedure, it has its own entries and exits. In particular, this means that the execution of advice can cause the procedure that it modifies to be bypassed completely, e.g., by specifying as an exit from the advice one of the exits from the original procedure; or the advice may change essential variables and continue with the computation so that the original procedure is executed, but with modified variables. Finally, the advice may not alter the execution or affect the original procedure at all, e.g., it may merely perform some additional computation such as printing a message or recording history. Since advice can be conditional, the decision as to what is to be done can depend on the results of the computation up to that point.▼
=== Readability ===
:The principal advantage of advising is that the user need not be concerned about the details of the actual changes in his program, nor the internal representation of advice. He can treat the procedure to be advised _as a unit_, a single block, and make changes to it without concern for the particulars of this block. This may be contrasted with editing in which the programmer must be cognizant of the internal structure of the procedure.▼
Advice has the potential to introduce confusion, as a piece of advice applied to a function is not apparent to a user who tracks down the function's source definition to learn about it. In such cases, advice acts almost like a [[COMEFROM]], a joke facility added to [[INTERCAL]] to spoof the [[Spaghetti code|spaghettification]] attendant to the extensive use of [[GOTO]]s. In practice, however, such issues rarely present themselves. [[Upstream (software development)|Upstream]] developers and maintainers of Lisp packages and modules never use advice, since there is no advantage to be gained by advising functions when their original source definitions can be freely rewritten to include the desired features. Advice is only useful in that it enables [[Downstream (software development)|downstream]] users to subsequently modify default behaviour in a way that does not require propagation of such modifications into the core implementation's source definition.
==Implementations==▼
"Advising" found its way into [[BBN Lisp]] and later into [[Xerox PARC]]'s [[Interlisp]].▼
A form of advices were part of [[C with Classes]] in the late 1970s and early 1980s, namely functions called <code>call</code> and <code>return</code> defined in a class, which were called before (respectively, after) member functions of the class. However, these were dropped from [[C++]].<ref>''The Design and Evolution of C++,'' p. 57</ref>▼
Advices are part of the [[Common Lisp Object System]] (CLOS), as <code>:before</code>, <code>:after</code>, and <code>:around</code> methods, which are combined with the primary method under "standard method combination".<ref>{{Cite web |url=http://www.aiai.ed.ac.uk/~jeff/clos-guide.html |title=A Brief Guide to CLOS |access-date=2015-04-27 |archive-url=https://web.archive.org/web/20150506043702/http://www.aiai.ed.ac.uk/~jeff/clos-guide.html |archive-date=2015-05-06 |url-status=dead }}</ref>▼
It also found its way to [[Flavors (programming language)|Flavors]], the first [[object-oriented programming|object-oriented]] extension to [[Lisp (programming language)|Lisp]] developed at [[MIT]]. They were subsumed under the notion of method combination. <ref>See, for example, AIM-602 at https://web.archive.org/web/20060913001624/http://www.ai.mit.edu/research/publications/browse/0600browse.shtml </ref>{{efn|name=fn1}}▼
Common Lisp implementations provide advice functionality (in addition to the standard method combination for CLOS) as extensions. LispWorks<ref>[http://www.lispworks.com/documentation/lw70/LW/html/lw-32.htm LispWorks 7 User Guide and Reference Manual, The Advice Facility]</ref> supports advising functions, macros and CLOS methods.▼
Since method combination and macros are closely related, it's also interesting to note that the first macro system was described in 1963, three years before Warren Teitelman's PhD thesis. <ref>See AIM-57 at https://web.archive.org/web/20060913001624/http://www.ai.mit.edu/research/publications/browse/0000browse.shtml </ref>{{efn|name=fn2}}▼
EmacsLisp added advice-related code in version [http://web.mit.edu/dosathena/sandbox/emacs-19.28/src/ChangeLog 19.28], 1994.▼
▲==Use==
▲The practical use of advice functions is generally to modify or otherwise extend the behavior of functions which cannot be easily modified or extended. The [[Emacspeak]] [[Emacs]]-addon makes extensive use of advice: it must modify thousands of existing Emacs modules and functions such that it can produce audio output for the blind corresponding to the visual presentation, but it would be infeasible to copy all of them and redefine them to produce audio output in addition to their normal outputs; so, the Emacspeak programmers define advice functions which run before and after.
==History ==
▲Another Emacs example; suppose after one corrected a misspelled word through [[ispell]], one wanted to re-spellcheck the entire buffer. <code>ispell-word</code> offers no such functionality, even if the spellchecked word is used a thousand times. One ''could'' track down the definition of <code>ispell-word</code>, copy it into one's .emacs, and write the additional functionality, but this is tedious, prone to broken-ness (the .emacs version will get out of sync with the actual Ispell Elisp module, if it even works out of its home). What one wants is fairly simple: just to run another command after <code>ispell-word</code> runs. Using advice functions, it can be done as simply as this:
▲The following is taken from a discussion at the mailing list [https://web.archive.org/web/20060513042952/http://aosd.net/pipermail/discuss_aosd.net/2004-November/001173.html aosd-discuss]. [[Pascal Costanza]] contributed the following:
▲The term
▲<source lang="elisp">
▲ (flyspell-buffer))
▲:Advising is the basic innovation in the model, and in the PILOT system. Advising consists of inserting new procedures at any or all of the entry or exit points to a particular procedure (or class of procedures). The procedures inserted are called "advice procedures" or simply "advice".
▲==Implementations==
:
▲A form of advices were part of [[C with Classes]] in the late 1970s and early 1980s, namely functions called <code>call</code> and <code>return</code> defined in a class, which were called before (respectively, after) member functions of the class. However, these were dropped from [[C++]].<ref>''The Design and Evolution of C++,'' p. 57</ref>
▲:Since each piece of advice is itself a procedure, it has its own entries and exits. In particular, this means that the execution of advice can cause the procedure that it modifies to be bypassed completely, e.g., by specifying as an exit from the advice one of the exits from the original procedure; or the advice may change essential variables and continue with the computation so that the original procedure is executed, but with modified variables. Finally, the advice may not alter the execution or affect the original procedure at all, e.g., it may merely perform some additional computation such as printing a message or recording history. Since advice can be conditional, the decision as to what is to be done can depend on the results of the computation up to that point.
:
▲:The principal advantage of advising is that the user need not be concerned about the details of the actual changes in his program, nor the internal representation of advice. He can treat the procedure to be advised
▲"Advising" found its way into [[BBN Lisp]] and later into [[Xerox PARC]]'s [[Interlisp]].
▲Advices are part of the [[Common Lisp Object System]] (CLOS), as <code>:before</code>, <code>:after</code>, and <code>:around</code> methods, which are combined with the primary method under "standard method combination".<ref>{{Cite web |url=http://www.aiai.ed.ac.uk/~jeff/clos-guide.html |title=A Brief Guide to CLOS |access-date=2015-04-27 |archive-url=https://web.archive.org/web/20150506043702/http://www.aiai.ed.ac.uk/~jeff/clos-guide.html |archive-date=2015-05-06 |url-status=dead }}</ref>
▲It also found its way to [[Flavors (programming language)|Flavors]], the first [[object-oriented programming|object-oriented]] extension to [[Lisp (programming language)|Lisp]] developed at [[MIT]]. They were subsumed under the notion of method combination.
▲Common Lisp implementations provide advice functionality (in addition to the standard method combination for CLOS) as extensions. LispWorks<ref>[http://www.lispworks.com/documentation/lw70/LW/html/lw-32.htm LispWorks 7 User Guide and Reference Manual, The Advice Facility]</ref> supports advising functions, macros and CLOS methods.
▲Since method combination and macros are closely related, it's also interesting to note that the first macro system was described in 1963, three years before Warren Teitelman's PhD thesis.
▲EmacsLisp added advice-related code in version [http://web.mit.edu/dosathena/sandbox/emacs-19.28/src/ChangeLog 19.28], 1994.
==See also ==
Line 45 ⟶ 50:
{{notelist|refs=
{{efn|name=fn1|Advice appeared separately from [[Flavors (Lisp)|Flavors]] in [[Maclisp]] and the [[Lisp Machine]]. You could advise any function, just like in Interlisp at the time. The before/after ontology appeared separately in Flavors methods.}}
{{efn|name=fn2|Method combination and macros were only marginally related until much later, in New Flavors and [[CLOS]], when a macro-like mechanism was provided to allow people to define their own rules for combining methods. Prior to that the rules governing combination of before/after methods and so-called whoppers methods (around) was fixed, and the compiler just generated the code for that. There were things called wrappers, which had macro-like behavior, but I forget when they came around. Traipsing through the various versions of MacLisp and Lispm manual to get this part of the history exactly right could be interesting. Or it could be that Howard Cannon or David Moon or someone could actually remember it all exactly.}}
}}
Line 52 ⟶ 57:
==External links==
* [http://www.ai.mit.edu/research/publications/browse/0200browse.shtml Teitelman's PhD thesis, PILOT: A Step Toward Man-Computer Symbiosis] (AITR-221)
* [http://bitsavers.informatik.uni-stuttgart.de/pdf/xerox/interlisp/Interlisp_Reference_Manual_1974.pdf Interlisp reference manual] from 1974
* [
{{aosd}}
Line 61 ⟶ 66:
[[Category:Lisp (programming language)]]
[[Category:Programming constructs]]
[[Category:Articles with example Lisp (programming language) code]]
|