unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* About `setf' with macro call
@ 2013-04-17 13:21 xfq
  2013-04-17 14:06 ` Tassilo Horn
  0 siblings, 1 reply; 5+ messages in thread
From: xfq @ 2013-04-17 13:21 UTC (permalink / raw)
  To: help-gnu-emacs

In (info "(cl) Setf Extensions"), there is a example about using `setf'
on a macro call:

  (defmacro wrong-order (x y) (list 'aref y x))
  (setf (wrong-order A B) 17)

I evaluated these two expressions, and debugger entered:

  Debugger entered--Lisp error: (void-variable B)
    (let* ((v B) (v A)) (aset v v 17))
    (setf (wrong-order A B) 17)
    eval((setf (wrong-order A B) 17) nil)
    eval-last-sexp-1(nil)
    eval-last-sexp(nil)
    call-interactively(eval-last-sexp nil nil)
    command-execute(eval-last-sexp)

I understand that `A' and `B' are two invalid S-expressions here.  But I
don't understand the `let*' expression in the backtrace.  Does it store
into the element of `B' or `A' at index `A' the value 17?

I'd like to search the web, but I don't know how.  Any ideas?

--
Best regards, Xue Fuqiao.
http://www.gnu.org/software/emacs/



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

* Re: About `setf' with macro call
  2013-04-17 13:21 About `setf' with macro call xfq
@ 2013-04-17 14:06 ` Tassilo Horn
  2013-04-17 15:03   ` Stefan Monnier
  0 siblings, 1 reply; 5+ messages in thread
From: Tassilo Horn @ 2013-04-17 14:06 UTC (permalink / raw)
  To: help-gnu-emacs

xfq <xfq.free@gmail.com> writes:

> In (info "(cl) Setf Extensions"), there is a example about using `setf'
> on a macro call:
>
>   (defmacro wrong-order (x y) (list 'aref y x))
>   (setf (wrong-order A B) 17)
>
> I evaluated these two expressions, and debugger entered:
>
>   Debugger entered--Lisp error: (void-variable B)
>     (let* ((v B) (v A)) (aset v v 17))
>     (setf (wrong-order A B) 17)
>     eval((setf (wrong-order A B) 17) nil)
>     eval-last-sexp-1(nil)
>     eval-last-sexp(nil)
>     call-interactively(eval-last-sexp nil nil)
>     command-execute(eval-last-sexp)
>
> I understand that `A' and `B' are two invalid S-expressions here.  But
> I don't understand the `let*' expression in the backtrace.

You need to have a look at the macro expansions to understand the
problem.

--8<---------------cut here---------------start------------->8---
ELISP> (macroexpand '(wrong-order A B))
(aref B A)
ELISP> (macroexpand '(setf (wrong-order A B) 17))
(let*
    ((v B)
     (v A))
  (aset v v 17))
--8<---------------cut here---------------end--------------->8---

Now that explains the let* in the backtrace, but the setf-expansion
looks totally wrong!  v is set to B (the index) and then overridden by A
(the array).  So aset becomes called with the array, the array again in
place where the index should be, and then the value to be set...

Let's try it with an example:

--8<---------------cut here---------------start------------->8---
ELISP> (defvar my-array (make-vector 10 1))
my-array
ELISP> my-array
[1 1 1 1 1 1 1 1 1 1]
ELISP> (setf (aref my-array 4) 3)
3
ELISP> my-array
[1 1 1 1 3 1 1 1 1 1]
ELISP> (setf (wrong-order 4 my-array) 17)
17
ELISP> my-array
[1 1 1 1 17 1 1 1 1 1]
--8<---------------cut here---------------end--------------->8---

Strange.  Although the macro expansion looks broken, it works anyhow?!
Now let's test the macro expansion manually.

--8<---------------cut here---------------start------------->8---
ELISP> (let* ((v 4) (v my-array)) (aset v v 19))
*** Eval error ***  Wrong type argument: integerp, [1 1 1 1 17 1 1 1 1 1]
--8<---------------cut here---------------end--------------->8---

Yes, that's what I expected also from the macro version...

Can anyone explain what's going on here?

Bye,
Tassilo




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

* Re: About `setf' with macro call
  2013-04-17 14:06 ` Tassilo Horn
@ 2013-04-17 15:03   ` Stefan Monnier
  2013-04-17 15:14     ` Tassilo Horn
  0 siblings, 1 reply; 5+ messages in thread
From: Stefan Monnier @ 2013-04-17 15:03 UTC (permalink / raw)
  To: help-gnu-emacs

ELISP> (macroexpand '(setf (wrong-order A B) 17))
> (let*
>     ((v B)
>      (v A))
>   (aset v v 17))
> --8<---------------cut here---------------end--------------->8---

> Now that explains the let* in the backtrace, but the setf-expansion
> looks totally wrong!  v is set to B (the index) and then overridden by A
> (the array).

Actually, no: try (setq print-gensym t) to see the full story.


        Stefan




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

* Re: About `setf' with macro call
  2013-04-17 15:03   ` Stefan Monnier
@ 2013-04-17 15:14     ` Tassilo Horn
  2013-04-20  0:46       ` xfq
  0 siblings, 1 reply; 5+ messages in thread
From: Tassilo Horn @ 2013-04-17 15:14 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> ELISP> (macroexpand '(setf (wrong-order A B) 17))
>> (let*
>>     ((v B)
>>      (v A))
>>   (aset v v 17))
>> --8<---------------cut here---------------end--------------->8---
>
>> Now that explains the let* in the backtrace, but the setf-expansion
>> looks totally wrong!  v is set to B (the index) and then overridden by A
>> (the array).
>
> Actually, no: try (setq print-gensym t) to see the full story.

Argh, it's not the first time I've fallen into that trap.  It happens so
rarely that at the Nth time I've usually forgotten about the N-1th time
and its explanation. ;-)

So now I've eventually put

  (setq print-gensym t
        print-circle t)

in my ~/.emacs, so hopefully I won't be caught another time.

Thanks,
Tassilo




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

* Re: About `setf' with macro call
  2013-04-17 15:14     ` Tassilo Horn
@ 2013-04-20  0:46       ` xfq
  0 siblings, 0 replies; 5+ messages in thread
From: xfq @ 2013-04-20  0:46 UTC (permalink / raw)
  To: help-gnu-emacs

Ah, I see.  Thanks you, Stefan and Tassilo.

On Wed, Apr 17, 2013 at 11:14 PM, Tassilo Horn <tsdh@gnu.org> wrote:
> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
>> ELISP> (macroexpand '(setf (wrong-order A B) 17))
>>> (let*
>>>     ((v B)
>>>      (v A))
>>>   (aset v v 17))
>>> --8<---------------cut here---------------end--------------->8---
>>
>>> Now that explains the let* in the backtrace, but the setf-expansion
>>> looks totally wrong!  v is set to B (the index) and then overridden by A
>>> (the array).
>>
>> Actually, no: try (setq print-gensym t) to see the full story.
>
> Argh, it's not the first time I've fallen into that trap.  It happens so
> rarely that at the Nth time I've usually forgotten about the N-1th time
> and its explanation. ;-)
>
> So now I've eventually put
>
>   (setq print-gensym t
>         print-circle t)
>
> in my ~/.emacs, so hopefully I won't be caught another time.
>
> Thanks,
> Tassilo
>
>



-- 
Best regards, Xue Fuqiao.
http://www.gnu.org/software/emacs/



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

end of thread, other threads:[~2013-04-20  0:46 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-17 13:21 About `setf' with macro call xfq
2013-04-17 14:06 ` Tassilo Horn
2013-04-17 15:03   ` Stefan Monnier
2013-04-17 15:14     ` Tassilo Horn
2013-04-20  0:46       ` xfq

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).