That's possible for functions bound to symbols, in the current environment:
(setf (symbol-function 'myfn) #'identity)
There is also (setf FDEFINTION)
which does mostly the same, but also supports setf
functions.
One can't do it for lexically bound functions (by FLET
and LABELS
).
Example how to set a symbol function using (setf fdefinition)
CL-USER 11 > (setf (fdefinition 'myfn) #'identity)
#<Function IDENTITY 410003F974>
CL-USER 12 > (myfn 10)
10
Further remarks
Note that it does that in the current environment. Thus
(defun myfn (x) x)
might be replaced by something like
(eval-when (:compile-toplevel :load-toplevel :execute)
(setf (fdefinition 'myfn) #'identity))
Tha advantage: the function would be known as usual during compilation.
One of the things to keep in mind:
The symbol object may carry some information. For example the original function name, if there was one:
CL-USER 13 > #'identity
#<Function IDENTITY 410003F974>
Setting the function cell of a symbol, does not change that:
CL-USER 14 > #'myfn
#<Function IDENTITY 410003F974>
It's the same function object with its original internal name. One may be able to access that name, but one can't change it:
CL-USER 18 > (nth-value 2 (function-lambda-expression #'identity))
IDENTITY
There is also a problem with self-recursive functions:
CL-USER 19 > (defun foo (n)
(if (zerop n)
1
(* n (foo (1- n))))) ; here foo calls the function foo
FOO
now we set BAR
to use the function FOO
CL-USER 20 > (setf (symbol-function 'bar) #'foo)
#<interpreted function FOO 4060004084>
CL-USER 21 > (bar 10)
3628800
Here we redefine FOO
:
CL-USER 22 > (defun foo (n)
(if (zerop n)
1
(+ n (foo (1- n)))))
FOO
BAR
still uses the old FOO
, which may or may not call the new FOO
.
CL-USER 23 > (bar 10)
460
OOPS! We changed FOO, but it has strange effects on BAR: the first iteration is the old FOO and the next recursive invocation is the new FOO.
BAR
and FOO
are two different versions of the same function. But both call the function FOO
, which may be the old or the new function - depending on how you interpret or compile the code.
CL-USER 24 > #'foo
#<interpreted function FOO 40600041F4>
CL-USER 25 > #'bar
#<interpreted function FOO 4060004084>