Say, an external package defines these functions:
(defun my/inner (x)
(1+ x))
(defun my/outer ()
(my/inner 7))
We want to create a function that wraps my/outer, replacing my/inner with the following:
(defun my/replacement (x)
(1- x))
Using advice, we can do it like so:
(defun my/wrapped1 ()
(add-function :override (symbol-function 'my/inner)
'my/replacement)
(unwind-protect
(my/outer)
(remove-function (symbol-function 'my/inner)
'my/replacement)))
What happens internally when using advice? I am unable to find good documentation on this topic.
The issue that interests me the most is the interaction between advice and byte compilation (Manual entry). The conclusion of This article from 12 years ago is that there is no way of using advising certain functions as they have their own bytecode instructions.
In particular, how is my/wrapped1 different from the following?
(defun my/wrapped2 ()
(cl-letf (((symbol-function 'my/inner)
'my/replacement))
(my/outer)))
Does this address any of these issues or is advice just a fancy API around editing the symbol-function of a function definition and thus these two are equivalent?
PS: There is also defalias but its docstring explicitly says it internally uses fset (i.e., equivalent to cl-letf)