From: Paul Bowyer <pbowyer@ol...> - 2012-07-06 20:05:42
I have the following macro defined thusly using SBCL-1.0.57 and Slime.
(defmacro get-callback-wrapper (callback)
(let* ((func-name (gensym))
(wrapper-name (intern (format nil "WRAPPER-~a" func-name) ))
`(defun ,wrapper-name (caller-instance)
(funcall ,callback) ;; User callbacks wont have arguments
When I call this macro using the following functions, it works perfectly
and I get different callback functions for each menuitem.
(create-user-menuitem "MyUserMenu" "MyEntryDialog"
(create-user-menuitem "MyUserMenu" "MyChoiceDialog"
(create-user-menuitem "MyUserMenu" "MyMessageDialog"
If I change the "create-user-menuitem" function so that it calls
"get-callback-wrapper" and I just pass the callbacks as symbols, I no
longer get different callbacks for each menuitem.
(defun create-user-menuitem (menu-title title call-back)
(let* ((mnu (get-menu-instance *new-instance* menu-title))
(mnufrm (get-menuitemframe-instance mnu))
(callbk (get-callback-wrapper call-back) )
(if (and mnu mnufrm) ;;We have a place to put it ; ;
(create-menuitem mnufrm mnu title callbk) ;;NOT passed in
(format t "Could not create menuitem!~%" ) ;;Error
)) ;;End let ; ;
(format t "new-instance undefined!~%") ;;Error
(create-user-menuitem "MyUserMenu" "MyEntryDialog" 'my-callback)
(create-user-menuitem "MyUserMenu" "MyChoiceDialog" 'my-callback2)
(create-user-menuitem "MyUserMenu" "MyMessageDialog" 'my-callback3)
All of the callback functions are known at compile time.
Should I not be able to rely on the compiler to call
"create-user-menuitem" with different callback arguments and have that
result in different calls to "get-callback-wrapper" rather than
returning the same wrapper for each menuitem?
I've asked this on a public mailing list and I've not found a suitable
Thanks in advance for any information that might be helpful in my
understanding this difficulty
In the second version, the macro expander is called once, during
*compilation* of create-user-menuitem.
This means that GENSYM is also only called once.
This is not an SBCL bug but the system doing what you ask it to do.
Assigning functions to symbols at runtime is possible, but overkill
for most applications. It is usually much simpler to just store the
callback as an anonymous lambda function.