From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Drew Adams" Newsgroups: gmane.emacs.help Subject: RE: What do 'hooks' do and how do they do it? Date: Sat, 1 Aug 2009 15:05:52 -0700 Message-ID: <92BB348CF47244E5A4BAB82CA4021A7A@us.oracle.com> References: <1249147043.2246.18.camel@CASE><86iqh7ct32.wl%djcb@djcbsoftware.nl> <1249159408.2246.35.camel@CASE> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1249164398 30645 80.91.229.12 (1 Aug 2009 22:06:38 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 1 Aug 2009 22:06:38 +0000 (UTC) Cc: 'Emacs Help List' To: "'William Case'" , Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Sun Aug 02 00:06:22 2009 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1MXMia-0003wG-D1 for geh-help-gnu-emacs@m.gmane.org; Sun, 02 Aug 2009 00:06:20 +0200 Original-Received: from localhost ([127.0.0.1]:57639 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MXMiZ-0005Uh-I7 for geh-help-gnu-emacs@m.gmane.org; Sat, 01 Aug 2009 18:06:19 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MXMiE-0005UJ-17 for help-gnu-emacs@gnu.org; Sat, 01 Aug 2009 18:05:58 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MXMi8-0005Ti-Ts for help-gnu-emacs@gnu.org; Sat, 01 Aug 2009 18:05:57 -0400 Original-Received: from [199.232.76.173] (port=42095 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MXMi8-0005Tf-QZ for help-gnu-emacs@gnu.org; Sat, 01 Aug 2009 18:05:52 -0400 Original-Received: from acsinet11.oracle.com ([141.146.126.233]:44649) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MXMi8-0005r7-27 for help-gnu-emacs@gnu.org; Sat, 01 Aug 2009 18:05:52 -0400 Original-Received: from rgminet15.oracle.com (rcsinet15.oracle.com [148.87.113.117]) by acsinet11.oracle.com (Switch-3.3.1/Switch-3.3.1) with ESMTP id n71M68jN022162 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sat, 1 Aug 2009 22:06:10 GMT Original-Received: from abhmt004.oracle.com (abhmt004.oracle.com [141.146.116.13]) by rgminet15.oracle.com (Switch-3.3.1/Switch-3.3.1) with ESMTP id n71M5iaj020120; Sat, 1 Aug 2009 22:05:44 GMT Original-Received: from dradamslap1 (/141.144.64.148) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sat, 01 Aug 2009 15:05:42 -0700 X-Mailer: Microsoft Office Outlook 11 Thread-Index: AcoS6SMoZsch8abQQ8+m/UEkQwvLUQAAIDww X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5579 In-Reply-To: <1249159408.2246.35.camel@CASE> X-Source-IP: abhmt004.oracle.com [141.146.116.13] X-Auth-Type: Internal IP X-CT-RefId: str=0001.0A010207.4A74BC37.0170:SCFSTAT5015188,ss=1,fgs=0 X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 1) X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:66633 Archived-At: > > I think Drew Adams gave a very clear answer about the Emacs > > implementation, > > Yes he did. However, I tried to point out in my original post that I > was aware of how to implement a 'hook' in emacs. Well, I did not explain how to implement a hook. I tried to explain what a hook is: "a way to allow easy code extension at predefined places". I explained that when a hook is run in Emacs, the calling code just calls a function (e.g. `run-hooks') that obtains the functions to invoke from a variable's value. That's what a hook _is_, for Emacs; that's not how to implement a hook. The general point is that (a) the call (when, why, etc.) is predefined, but (b) what to call is determined dynamically (from the value of a variable, in the case of Emacs). In particular, in Emacs, hooking has _nothing to do with events_. Invocation of a hook function in Emacs is _not_ event-driven. > > but let me add that the concept of a 'hook' is simply a > > programming technique: the ability to set some function > > to be run whenever a particular event happens. Nope. (Unless the code that runs the hook variable happens to examine events to determine whether to call `run-hooks'.) The call to invoke the hook functions is static. The functions to invoke are determined dynamically by the value of a variable. The hook is the static part; what's hooked is the dynamic part - think of hooking a fish, if you like. > I was curious about the programming technique that was used -- or more > specifically -- how the hook function was setup so that the hook > automagically responded to a program's hook event. There is nothing automagical here, and there is no hook event. > > The concept is in use in many places (such as SE-Linux), > > but how it's implemented is quite different. In Emacs-Lisp, > > the hooks are simply Lisp functions to be called -- no kernel > > involved (well...). No. The "hooks" are the hook variables plus the calls to `run-hooks' that use those variables, both of which are essentially static code. The values of the hook variables are dynamic, and they determine which functions (the "hook functions") get called. The functions called by the hooks are not the hooks; the variables are the hooks. More generally, a "hook" is a predefined call to something to be determined outside the static calling code. It is, well, a "hook" on which you can hang any code you want executed. Hooks are static things; dynamic things are hung on the hooks. Think coat hooks (stable, static) and coats that might be hung there (movable, dynamic, changeable set). The hanging typically takes place at a different time from the definition of the code that has the hook (the building of the coat rack). That's the point: decouple where to do something from what actually gets done there. Those are determined at different times: code writing vs runtime. Connecting (a) the actual functions to be called to (b) the hook that is made available for calling them is, in effect, a form of dynamic or late binding. In the case of Emacs, this is simply the binding of a variable to its value. This is akin to (funcall foo): the (functional) value of variable `foo' is obtained at runtime, and it is called as a function. (funcall foo) is a kind of "hook", on which is hung the value of `foo' at runtime. (But in Emacs we generally reserve "hook" for a hook variable. Nevertheless, the overall concept here is the same.) Note that in environments that are much less dynamic than Emacs and Lisp, hooks can have greater importance: they are sometimes the _only_ effective way for user code to be plugged into the main (binary) code. In the early days, giving users a way to branch their own calls into the main code was sometimes called a "user exit". (A hook that was hidden was sometimes called a "back door".) "User exit" pretty much sums up this claustrophobic state of affairs: it was the only way to escape from the program to do something extra or different. > > See: http://en.wikipedia.org/wiki/Hooking > > The wikipedia site you suggest above covers just about everything I > wanted to know. I don't know how I missed it. Most of that page does not particularly apply to Emacs hooks, I'm afraid. The general idea applies, but most of the hook mechanisms described on that page have little relation to Emacs hooks. What is most helpful on that page wrt Emacs hooks are the two sentences that constitute the (entire) section "Emacs": "Hooks are an important mechanism for customization of Emacs. A hook is a Lisp variable which holds a list of functions, to be called on some well-defined occasion. (This is called running the hook.)" The "well-defined occasion" and the hook variable together constitute the stable, "hook" part. The functions on the list at any given time are the dynamic, "hung" part. The best explanation of Emacs hooks and hooking remains the Emacs doc (which is why I pointed you to it, and Wikipedia does likewise). HTH.