[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Need some education on defmacro define-toggle

From: Lennart Borgman
Subject: Re: Need some education on defmacro define-toggle
Date: Mon, 28 Dec 2009 22:58:49 +0100

On Mon, Dec 28, 2009 at 10:33 PM, Pascal J. Bourguignon
<address@hidden> wrote:
> Lennart Borgman <address@hidden> writes:
>> On Mon, Dec 28, 2009 at 6:16 AM, Lennart Borgman
>> <address@hidden> wrote:
>>> I just got into some trouble because of a badly written macro I
>>> believe. After the long discussions about defmacro here I wonder if
>>> anyone wants to help me out. How should I write the defmacro below?
>> I resorted to self education (which is not too bad). However I still
>> got problems - just on a more complicated level. The macro now looks
>> like this:
>> (defmacro define-toggle (symbol value doc &rest args)
>>   "Declare SYMBOL as a customizable variable with a toggle function."
>>   (declare   (doc-string 3)   (debug t))
>>   (let* ((SYMBOL-toggle (intern (concat (symbol-name symbol) "-toggle")))
>>          (SYMBOL-name (symbol-name symbol))
>>          (var-doc doc)
>>          (fun-doc (concat "Toggles the \(boolean) value of `" SYMBOL-name
>>                           "'.\nFor how to set it permanently see this
>> variable.\n")))
>>     (let ((var (append `(defcustom ,symbol ,value ,var-doc)
>>                 args
>>                 nil))
>>           (fun `(defun ,SYMBOL-toggle ()
>>                    ,fun-doc
>>                    (interactive)
>>                    (customize-set-variable (quote ,symbol) (not ,symbol)))))
>>       `(list 'progn ,var ,fun))))
>> This seems to work, but if the call to define-toggle already has been
>> done then loading a file with this define-toggle gives trouble:
>> Debugger entered--Lisp error: (void-variable 
>> rngalt-display-validation-header-toggle)
>>   (progn rngalt-display-validation-header 
>> rngalt-display-validation-header-toggle)
>>   (define-toggle rngalt-display-validation-header t "Display XML validation 
>> headers at the top of buffer when t.\nThe validation header is only 
>> displayed in buffers where the main\nmajor mode is derivd from `nxml-mode'." 
>> :set (lambda (sym val) (set-default sym val) 
>> (rngalt-update-validation-header-overlay-everywhere)) :group (quote 
>> relax-ng) :group (quote nxhtml))
>> ...
>> There is obviously something I got wrong in the evaluation order since
>> now, in this situation, the macro now tries to evaluate
>>   (progn rngalt-display-validation-header 
>> rngalt-display-validation-header-toggle)
>> I expected it to redefine the defcustom and the defun instead.
>> Can someone please try to explain what is going on?
> There must be an eval somewhere that tries to evaluate one time too many.

Hm, yes, but it is not mine...

As you can see from the backtrace there is some eval-buffer in the stack.

> That said, why doesn't your macro just return
>   `(progn ,var ,fun)
> instead of returning a list form that evaluates to something such as
>   (progn rngalt-display-validation-header 
> rngalt-display-validation-header-toggle)
> that needs to be evaluated (and of course fails since you didn't
> define these symbols as variables)?

It fails sometimes, but not always. It looks like it has something to
do with those eval above, but I do not understand how. If I just do
eval-buffer it works as I expect it to.

I have done some small changes and at the moment it seems to work, but
I have no idea why... There is clearly something in the order of
evaluation that beats me. If I just print out the values of fun and
var before comuting the result to return they look as I expect them
to, ie they are lists. But then in the progn list they are converted
to symbols, in some step.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]