+.sh 2 Evalhook\ and\ Funcallhook
+.pp
+There are hooks in the
+.Fr
+interpreter to permit a user written function to gain control of the
+evaluation process.
+These hooks are used by the Step package just described.
+There are two hooks and they have been strategically placed in the
+two key functions in the interpreter:
+.i eval
+(which all interpreted code goes through)
+and
+.i funcall
+(which all compiled code goes through if \fI(sstatus\ translink\ nil)\fP
+has been done).
+The hook in
+.i eval
+is compatible with Maclisp, but there is no
+Maclisp equivalent of the hook in
+.i funcall .
+.pp
+To arm the hooks two forms must be evaluated: \fI(*rset\ t)\fP and
+\fI(sstatus\ evalhook\ t)\fP.
+Once that is done,
+.i eval
+and
+.i funcall
+do a special check when they enter.
+.pp
+If
+.i eval
+is given a form to evaluate, say \fI(foo\ bar)\fP,
+and the symbol `evalhook' is non nil, say its value is `ehook',
+then
+.i eval
+will lambda bind the symbols `evalhook' and `funcallhook'
+to nil and will call ehook passing \fI(foo\ bar)\fP as the argument.
+It is ehook's responsibility to evaluate \fI(foo\ bar)\fP and
+return its value.
+Typically ehook will call the function `evalhook'
+to evaluate \fI(foo\ bar)\fP.
+Note that `evalhook' is a symbol whose function binding is a system function
+described in Chapter 4, and whose value binding, if non nil, is the
+name of a user written
+function (or a lambda expression, or a binary object) which
+will gain control whenever eval is called.
+`evalhook' is also the name of the
+.i status
+tag which must be set for
+all of this to work.
+.pp
+If
+.i funcall
+is given a function, say foo, and a set of already evaluated
+arguments, say barv and bazv, and if the symbol `funcallhook'
+has a non nil value, say `fhook', then
+.i funcall
+will lambda bind `evalhook' and `funcallhook' to nil
+and will call fhook with arguments barv, bazv and foo.
+Thus fhook must be a lexpr since it may be given any number
+of arguments.
+The function to call, foo in this case, will be the
+.i last
+of the arguments given to fhook.
+It is fhooks responsibility to do the function call and return the
+value.
+Typically fhook will call the function
+.i funcallhook
+to do the funcall.
+This is an example of a funcallhook function which just prints
+the arguments on each entry to funcall and the return value.
+.Eb
+-> \fI(defun fhook n (let ((form (cons (arg n) (listify (1- n))))
+ (retval))
+ (patom "calling ")(print form)(terpr)
+ (setq retval (funcallhook form 'fhook))
+ (patom "returns ")(print retval)(terpr)
+ retval))\fP
+fhook
+-> \fI(*rset t) (sstatus evalhook t) (sstatus translink nil)\fP
+-> \fI(setq funcallhook 'fhook)\fP
+calling (print fhook) ;; now all compiled code is traced
+fhookreturns nil
+calling (terpr)
+
+returns nil
+calling (patom "-> ")
+-> returns "-> "
+calling (read nil Q00000)
+\fI(array foo t 10)\fP ;; to test it, we see what happens when
+returns (array foo t 10) ;; we make an array
+calling (eval (array foo t 10))
+calling (append (10) nil)
+returns (10)
+calling (lessp 1 1)
+returns nil
+calling (apply times (10))
+returns 10
+calling (small-segment value 10)
+calling (boole 4 137 127)
+returns 128
+ ... there is plenty more ...
+.Ee