[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: |
Tue, 29 Dec 2009 01:49:30 +0100 |
On Tue, Dec 29, 2009 at 1:37 AM, Pascal J. Bourguignon
<pjb@informatimago.com> wrote:
> Lennart Borgman <lennart.borgman@gmail.com> writes:
>
>> On Mon, Dec 28, 2009 at 10:33 PM, Pascal J. Bourguignon
>> <pjb@informatimago.com> wrote:
>>> Lennart Borgman <lennart.borgman@gmail.com> writes:
>>>
>>>> On Mon, Dec 28, 2009 at 6:16 AM, Lennart Borgman
>>>> <lennart.borgman@gmail.com> 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))))
>>
>>
>>> 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.
>
> Of course, when you evaluate `(list 'progn ,defcustom-form ,defun-form)
> the defcustom and the defun are evaluated, and they return their name
> argument.
Hm, in that case the defcustom and defun must have been evaluated
earlier because they did exist. Now I have changed this so many times
so I am not sure when.
> That's why I advise you to write instead:
>
> `(progn ,defcustom-form ,defun-form)
Thanks, yes, I understand that. I tried a lot of alternatives though
to get evaluation at the right time. Surprisingly enough it sometimes
worked with `(list 'prog ,var ,fun) and sometimes not.
I did not dig deep in this, because I know there are other people here
who understands this much better than me ... ;-)
In the current implementation (which seems to work) I have this
(let ((var (append `(defcustom ,symbol ,value ,var-doc)
args
nil))
(fun `(defun ,SYMBOL-toggle ()
,fun-doc
(interactive)
(customize-set-variable (quote ,symbol) (not ,symbol)))))
`(progn ,fun ,var)
)))
Does that look correct?