In emacs lisp (but answers relating to common lisp are also welcome) I have a library that uses a macro and I want to hijack one of the macro's arguments only when executed in a certain context. Essentially what I want is a macro:
; My macro. This is a sketch of what I want that doesn't work.
(defmacro hijack-f (body)
`(macrolet ((f (x) `(f (+ 1 ,x))))
,@body))
; Defined in the library, I don't want to deal with these
(defmacro f (x) x)
(defun g (x) (f x))
So that
(g 1) ; => 1
(hijack-f (g 1)) ; => 2
(hijack-f (hijack-f (g 1))) ; => 3
EDIT: @melpomene and @reiner-joswig correctly point out that f
is expanded in g
before hijack-f
. As a followup is there a hijack-f
such that:
(f 1) ; => 1
(hijack-f (f 1)) ; => 2
(hijack-f (hijack-f (f 1))) ; => 3
As far as I know, what you want is not possible because g
does not contain an invocation of f
. Instead f
runs first and expands to (part of) the definition of g
.
That is:
(defun g (x) (f x))
immediately turns into
(defun g (x) x)
Which then defines g
as a function (whose value is (lambda (x) x)
).
Messing with f
at runtime doesn't affect anything because its invocation is long gone by the time you call g
.