Sometimes I want to generate a function programmatically as opposed to defining
defun. You may wondering why I'd want to do this. Well, it's
complicated but just bear with me for a moment.
(defun void-defun (fn) (let ((name (gensym "void-defun-"))) (eval `(progn (message "Created function: %S" name) (defun ,name () (funcall #',fn)))) name))
When I test whether the function is bound with the following code, all is well.
(let ((fn (void-defun (lambda () 2)))) (and (fboundp fn) (= 2 (funcall fn)) fn)) ;; => void-defun-69
after the test
However, after evaluating this test code and calling the function (whose name I
know from the
*messages* buffer) I get a void-function error. I expected the
function to be bound as indicated by my test. It is as if the function was bound
temporarily for the execution of my test form then unbound again.
;; This 69 is just as an example of a name I could get. (funcall #'void-defun-69) ;; => eval: Symbol’s function definition is void: void-defun-69
Why does this happen? And how can I avoid this?
defun!which is the same as
defunexcept that after the docstring it is possible to supply keyword arguments such as
(defun! fn () (:expire t) (:after message) (message "Just messaged")). This would result in a function that is an after advice to
messageand would unbind itself after its first call. I have wanted to call this macro via a function e.g. (void-defun (lambda () (message "hi") :expire t :after #'hi). I've heard it is not good practice to use eval. Before this I had
(funcall (backquote (lambda () ...))to avoid