(hook-combinator hook-id combinator-key).
The hook combinator is intended to be frozen by the hook definer, because the hook definer makes assumptions about the effects and the returned value of a hook.
The combinator key controls the application process and the hook-value in the case where one or more procedures are attached to the hook. Relative to the temporal ordering of attached procedures there are combinators that return the first, the first non-nil, the last, the list, and the sum of the individual applications.
More precisely, assume that the procedures , , ..., have been attached to a hook, by first attaching , then , and so on, until . The hook-combinator receives two arguments: (1) the list ( ... ) and (2) the argument list on which the procedures are to be applied. The combinator is in control of the order in which through are applied, and of the result returned from the hook construct.
The combinator called first executes the procedures in attachment-order (in the order through ), and it returns the value of the first of these (the value of applied on the argument list). The last combinator also executes the procedure in attachment-order, but it returns the value of the last of these applications. The fist-non-nil combinator similarly executes the procedure in attachment order, but only until one of the applications gives a non-nil value, which becomes the returned value. Three additional combinations are defined (first-reverse, last-reverse, and first-non-nil-reverse) that work in ways similar to first, last, and first-non-nil, but on the reverse attachment order. Finally, the sum and the list combinators give the + and the list reductions respectively of the individual results.
Last is the most common hook combinator, and it is therefore the default. This reflects the philosophy that the latest attachment should have the highest degree of control---namely control of the value of the hook construct, and the ability to undo results of earlier attachments (if possible). The other combinators may, however, bee useful too. As an example, the combinator first-non-nil-reverse, which applies the attached procedure in reverse order until one of them returns a non-nil result, is useful in case a program is customized in several steps. In such a situation, a late customization may veto the application of earlier customizations by applying this combinator. (A veto is signaled by returning a non-nil result from an attached procedure). The combinations list and sum are useful if we want all attached procedures to contribute equally and accumulative to the value of the hook construct.
The hook framework itself is open in the sense that it is possible to define new combinator keys and associated combination procedures.