From: Vijay M. <vij...@gm...> - 2013-08-11 07:27:12
|
I have the following macro definition which takes a symbol as argument and defines a new function. The symbol is used as the new function name: (defmacro make-fn (fn-name) `(defun ,fn-name () (format t "~a~%" ',fn-name))) The macro seems to work correctly: CL-USER> (make-fn my-function) MY-FUNCTION CL-USER> (my-function) MY-FUNCTION But when it is called from within the `dolist` macro a function with name `fn-name` is defined: (defparameter *fn-names* '(func01 func02)) (dolist (fn-name *fn-names*) (make-fn fn-name)) CL-USER> (func01) Error: FUNC02 is undefined. CL-USER> (fn-name) FN-NAME What is wrong with the macro definition? Thank you, --Vijay |
From: <ded...@ya...> - 2013-08-11 08:37:23
|
>I have the following macro definition which takes a symbol as argument and >defines a new function. The symbol is used as the new function name: > >(defmacro make-fn (fn-name) > `(defun ,fn-name () > (format t "~a~%" ',fn-name))) > >The macro seems to work correctly: > >CL-USER> (make-fn my-function) >MY-FUNCTION >CL-USER> (my-function) >MY-FUNCTION > >But when it is called from within the `dolist` macro a function with name >`fn-name` is defined: > >(defparameter *fn-names* '(func01 func02)) > >(dolist (fn-name *fn-names*) > (make-fn fn-name)) > >CL-USER> (func01) >Error: FUNC02 is undefined. >CL-USER> (fn-name) >FN-NAME > >What is wrong with the macro definition? I am not sure what you want is achievable with macros without changing the calling code. Macros get as their parameters literal unevaluated parts of code of their invokation. Macros get expanded in compile-time, before code is run. So in your code the macro call doesn't know it is inside dolist and only knows it is called as (make-fn fn-name). So it works just like in the first example. I would just write a second macro that generates a progn: (defmacro make-fns (fn-names) `(progn ,@(loop for fn-name in fn-names collect `(make-fn ,fn-name)))) (make-fns (func-01 func-02)) |
From: Pascal J. B. <pj...@in...> - 2013-08-11 10:24:18
|
Vijay Mathew <vij...@gm...> writes: > I have the following macro definition which takes a symbol as argument > and defines a new function. The symbol is used as the new function > name: > > (defmacro make-fn (fn-name) > `(defun ,fn-name () > (format t "~a~%" ',fn-name))) > > The macro seems to work correctly: > > CL-USER> (make-fn my-function) > MY-FUNCTION > CL-USER> (my-function) > MY-FUNCTION > > But when it is called from within the `dolist` macro a function with > name `fn-name` is defined: > > (defparameter *fn-names* '(func01 func02)) > > (dolist (fn-name *fn-names*) > (make-fn fn-name)) > > CL-USER> (func01) > Error: FUNC02 is undefined. > CL-USER> (fn-name) > FN-NAME > > What is wrong with the macro definition? There's nothing wrong in the macro. There's something wrong in your expectations. Macros work at macroexpansion time (usually included at compilation time). They don't have access to run-time data (run-time data may never exist (if you don't run the program), or may exist in one thousand years (if you only run it then), or may exist in trillion instances (if you run it in a loop). If you want to do something at run-time, then write a function: (defun make-function (fname) (setf (symbol-function fname) (lambda () (format t "~A~%" fname)))) (mapcar (function funcall) (mapcar (function make-function) '(func01 func02))) prints: func01 func02 --> (nil nil) Notice how in the CLHS, operators named DEFsomething are usually macros, while operators named MAKE-something are usually functions. -- __Pascal Bourguignon__ http://www.informatimago.com/ |