Следующее должно делать то, что вы ищете
(defmacro with-replaced-function (fdef &rest body)
(let ((oldf (gensym))
(result (gensym))
(name (car fdef))
(args (cadr fdef))
(rbody (cddr fdef)))
`(let ((,oldf (symbol-function ',name)))
(setf (symbol-function ',name) (lambda ,args ,@rbody))
(let ((,result (progn ,@body)))
(setf (symbol-function ',name) ,oldf)
,result))))
(defmacro show (x)
`(format t "~a --> ~a~%"
',x ,x))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun foo (x y) (+ x y))
(defun bar (x) (foo x (* x 2)))
(show (bar 42))
(show (with-replaced-function (foo (x y) (* x y))
(bar 42)))
(show (bar 42))
Макрос просто сохраняет функцию, указанную в данный момент символом, и заменяет ее предоставленной реализацией заглушки. В конце кадра функция восстанавливается до исходного значения.
Возможно, имеет смысл добавить защиту от нелокальных выходов из тела.
Обратите внимание, что очевидно, что изменение определения функции не будет работать, если вызов функции был встроен компилятором. CL имеет специальное объявление NOTINLINE , которое можно использовать для предотвращения этой проблемы.