all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* About `macroexpand'
@ 2012-12-30  2:39 Xue Fuqiao
  2012-12-30  3:50 ` Filipp Gunbin
  0 siblings, 1 reply; 5+ messages in thread
From: Xue Fuqiao @ 2012-12-30  2:39 UTC (permalink / raw)
  To: help-gnu-emacs

I wrote the following code:
(defmacro t-becomes-nil (variable)
  (if (eq variable t)
      (setq variable nil)))
(setq foo t)
(macroexpand '(t-becomes-nil foo))

The return value of `macroexpand' is nil.  I don't know why.  I think it should be:
(if (eq foo t)
    (setq foo nil)))

Can anybody help?
-- 
Best regards.



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: About `macroexpand'
  2012-12-30  2:39 About `macroexpand' Xue Fuqiao
@ 2012-12-30  3:50 ` Filipp Gunbin
  2012-12-30  5:35   ` Xue Fuqiao
  0 siblings, 1 reply; 5+ messages in thread
From: Filipp Gunbin @ 2012-12-30  3:50 UTC (permalink / raw)
  To: Xue Fuqiao; +Cc: help-gnu-emacs

On 30/12/2012 06:39, Xue Fuqiao wrote:

> I wrote the following code:
> (defmacro t-becomes-nil (variable)
>   (if (eq variable t)
>       (setq variable nil)))
> (setq foo t)
> (macroexpand '(t-becomes-nil foo))
>
> The return value of `macroexpand' is nil.  I don't know why.  I think it should be:
> (if (eq foo t)
>     (setq foo nil)))
>
> Can anybody help?

Inside your macro, the formal argument `variable' evaluates to `foo'
(that is, the actual argument, which _not yet evaluated_ itself). 
Then it's value (`foo') is compared by `eq' with 't' and possibly
overwritten with `nil'. The comparison doesn't make any sense and what
is actually overwritten is the local value of `variable'.

A correct version is like that:

(defmacro t-becomes-nil (variable)
  `(if (eq ,variable t)
       (setq ,variable nil)))

This returns the list after the backquote as written except the
`,variable' is substituted for the local value of `variable', which is
`foo'. Then the calling program can evaluate the resulting form to
obtain final result.

More on this: (info "(elisp) Wrong Time").

-- 
Filipp Gunbin



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: About `macroexpand'
  2012-12-30  3:50 ` Filipp Gunbin
@ 2012-12-30  5:35   ` Xue Fuqiao
  2012-12-30  7:06     ` Filipp Gunbin
  0 siblings, 1 reply; 5+ messages in thread
From: Xue Fuqiao @ 2012-12-30  5:35 UTC (permalink / raw)
  To: Filipp Gunbin; +Cc: help-gnu-emacs

On Sun, 30 Dec 2012 07:50:45 +0400
Filipp Gunbin <fgunbin@fastmail.fm> wrote:

> The comparison doesn't make any sense and what
> is actually overwritten is the local value of `variable'.

I still don't understand.  I tried this:
(defmacro t-becomes-nil (variable)
  (list 'if (list 'eq variable t)
      (list 'setq variable nil)))
(setq foo t)
(macroexpand '(t-becomes-nil foo))

But it returns (if (eq foo t) (setq foo nil)))
What's the difference between these two macros?
-- 
Best regards.



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: About `macroexpand'
  2012-12-30  5:35   ` Xue Fuqiao
@ 2012-12-30  7:06     ` Filipp Gunbin
  2012-12-30  7:40       ` Xue Fuqiao
  0 siblings, 1 reply; 5+ messages in thread
From: Filipp Gunbin @ 2012-12-30  7:06 UTC (permalink / raw)
  To: Xue Fuqiao; +Cc: help-gnu-emacs

On 30/12/2012 09:35, Xue Fuqiao wrote:

> On Sun, 30 Dec 2012 07:50:45 +0400
> Filipp Gunbin <fgunbin@fastmail.fm> wrote:
>
>> The comparison doesn't make any sense and what
>> is actually overwritten is the local value of `variable'.
>
> I still don't understand.  I tried this:
> (defmacro t-becomes-nil (variable)
>   (list 'if (list 'eq variable t)
>       (list 'setq variable nil)))
> (setq foo t)
> (macroexpand '(t-becomes-nil foo))
>
> But it returns (if (eq foo t) (setq foo nil)))
> What's the difference between these two macros?

This version is correct because it returns a form which can be
evaluated. 

The difference between your first and second version is that the first
does the (incorrect) computation itself (so macroexpand doesn't return
anything) and the second returns the form (and macroexpand shows it)
which can be in turn evaluated - and that is a correct macro.

The backquote in my example is just a special syntax which helps to
avoid complex `(list ...)' constructs with lots of quoting like those
you used.

-- 
Filipp Gunbin



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: About `macroexpand'
  2012-12-30  7:06     ` Filipp Gunbin
@ 2012-12-30  7:40       ` Xue Fuqiao
  0 siblings, 0 replies; 5+ messages in thread
From: Xue Fuqiao @ 2012-12-30  7:40 UTC (permalink / raw)
  To: Filipp Gunbin; +Cc: help-gnu-emacs

On Sun, 30 Dec 2012 11:06:46 +0400
Filipp Gunbin <fgunbin@fastmail.fm> wrote:

> This version is correct because it returns a form which can be
> evaluated. 
> 
> The difference between your first and second version is that the first
> does the (incorrect) computation itself (so macroexpand doesn't return
> anything) and the second returns the form (and macroexpand shows it)
> which can be in turn evaluated - and that is a correct macro.
> 
> The backquote in my example is just a special syntax which helps to
> avoid complex `(list ...)' constructs with lots of quoting like those
> you used.

I see, thanks.
-- 
Best regards.



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-12-30  7:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-30  2:39 About `macroexpand' Xue Fuqiao
2012-12-30  3:50 ` Filipp Gunbin
2012-12-30  5:35   ` Xue Fuqiao
2012-12-30  7:06     ` Filipp Gunbin
2012-12-30  7:40       ` Xue Fuqiao

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.