unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* "defmacro" and "local variables" and "let" and "nconc" strange behaviour...
@ 2013-01-13 14:15 Oleksandr Gavenko
  2013-01-13 14:18 ` Oleksandr Gavenko
       [not found] ` <mailman.17291.1358086805.855.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 7+ messages in thread
From: Oleksandr Gavenko @ 2013-01-13 14:15 UTC (permalink / raw)
  To: help-gnu-emacs

I wrote simple macro:

  (defmacro my-filter (pred list)
    "Construct list with elements from LIST which satisfy PRED."
    (let ( (r (make-symbol "r_")) )
      `(let ( (,r '(nil)) )
         (mapc (lambda (item)
                 (when (,pred item)
                   (nconc ,r (cons item nil))))
               ,list)
         (cdr ,r))))

When I evaluate several times:

  (my-filter (lambda (x) x) '(1 nil "a"))

I get sequentially:

  (1 "a")
  (1 "a" 1 "a")
  (1 "a" 1 "a" 1 "a")
  (1 "a" 1 "a" 1 "a" 1 "a")

When I eval:

  (pp (macroexpand '(my-filter (lambda (x) x) '(1 nil "a"))))

I get:

  (let
      ((r_
        '(nil 1 "a" 1 "a" 1 "a" 1 "a" 1 "a" 1 "a" 1 "a" 1 "a")))
    (mapc
     (lambda
       (item)
       (when
           ((lambda
              (x)
              x)
            item)
         (nconc r_
                (cons item nil))))
     '(1 nil "a"))
    (cdr r_))

Why instead of '(nil) I get something else?

-- 
Best regards!




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

* Re: "defmacro" and "local variables" and "let" and "nconc" strange behaviour...
  2013-01-13 14:15 "defmacro" and "local variables" and "let" and "nconc" strange behaviour Oleksandr Gavenko
@ 2013-01-13 14:18 ` Oleksandr Gavenko
       [not found] ` <mailman.17291.1358086805.855.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 7+ messages in thread
From: Oleksandr Gavenko @ 2013-01-13 14:18 UTC (permalink / raw)
  To: help-gnu-emacs

On 2013-01-13, Oleksandr Gavenko wrote:

> I wrote simple macro:
>
>   (defmacro my-filter (pred list)
>     "Construct list with elements from LIST which satisfy PRED."
>     (let ( (r (make-symbol "r_")) )
>       `(let ( (,r '(nil)) )
>          (mapc (lambda (item)
>                  (when (,pred item)
>                    (nconc ,r (cons item nil))))
>                ,list)
>          (cdr ,r))))
>
> When I evaluate several times:
>
>   (my-filter (lambda (x) x) '(1 nil "a"))
>
> I get sequentially:
>
>   (1 "a")
>   (1 "a" 1 "a")
>   (1 "a" 1 "a" 1 "a")
>   (1 "a" 1 "a" 1 "a" 1 "a")
>
> When I eval:
>
>   (pp (macroexpand '(my-filter (lambda (x) x) '(1 nil "a"))))
>
> I get:
>
>   (let
>       ((r_
>         '(nil 1 "a" 1 "a" 1 "a" 1 "a" 1 "a" 1 "a" 1 "a" 1 "a")))
>     (mapc
>      (lambda
>        (item)
>        (when
>            ((lambda
>               (x)
>               x)
>             item)
>          (nconc r_
>                 (cons item nil))))
>      '(1 nil "a"))
>     (cdr r_))
>
> Why instead of '(nil) I get something else?

I found fix by changing '(nil) to (list nil). Please explain why first variant
fail?

-- 
Best regards!




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

* Re: "defmacro" and "local variables" and "let" and "nconc" strange behaviour...
       [not found] <mailman.17290.1358086558.855.help-gnu-emacs@gnu.org>
@ 2013-01-13 14:21 ` Barry Margolin
  2013-01-13 15:00   ` Oleksandr Gavenko
  0 siblings, 1 reply; 7+ messages in thread
From: Barry Margolin @ 2013-01-13 14:21 UTC (permalink / raw)
  To: help-gnu-emacs

In article <mailman.17290.1358086558.855.help-gnu-emacs@gnu.org>,
 Oleksandr Gavenko <gavenkoa@gmail.com> wrote:

> I wrote simple macro:
> 
>   (defmacro my-filter (pred list)
>     "Construct list with elements from LIST which satisfy PRED."
>     (let ( (r (make-symbol "r_")) )
>       `(let ( (,r '(nil)) )
>          (mapc (lambda (item)
>                  (when (,pred item)
>                    (nconc ,r (cons item nil))))
>                ,list)
>          (cdr ,r))))
> 
> When I evaluate several times:
> 
>   (my-filter (lambda (x) x) '(1 nil "a"))
> 
> I get sequentially:
> 
>   (1 "a")
>   (1 "a" 1 "a")
>   (1 "a" 1 "a" 1 "a")
>   (1 "a" 1 "a" 1 "a" 1 "a")
> 
> When I eval:
> 
>   (pp (macroexpand '(my-filter (lambda (x) x) '(1 nil "a"))))
> 
> I get:
> 
>   (let
>       ((r_
>         '(nil 1 "a" 1 "a" 1 "a" 1 "a" 1 "a" 1 "a" 1 "a" 1 "a")))
>     (mapc
>      (lambda
>        (item)
>        (when
>            ((lambda
>               (x)
>               x)
>             item)
>          (nconc r_
>                 (cons item nil))))
>      '(1 nil "a"))
>     (cdr r_))
> 
> Why instead of '(nil) I get something else?

Because nconc is destructively modifying its own source code.

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***


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

* Re: "defmacro" and "local variables" and "let" and "nconc" strange behaviour...
  2013-01-13 14:21 ` Barry Margolin
@ 2013-01-13 15:00   ` Oleksandr Gavenko
  2013-01-13 16:45     ` Le Wang
  0 siblings, 1 reply; 7+ messages in thread
From: Oleksandr Gavenko @ 2013-01-13 15:00 UTC (permalink / raw)
  To: help-gnu-emacs

On 2013-01-13, Barry Margolin wrote:

> In article <mailman.17290.1358086558.855.help-gnu-emacs@gnu.org>,
>  Oleksandr Gavenko <gavenkoa@gmail.com> wrote:
>
>> I wrote simple macro:
>> 
>>   (defmacro my-filter (pred list)
>>     "Construct list with elements from LIST which satisfy PRED."
>>     (let ( (r (make-symbol "r_")) )
>>       `(let ( (,r '(nil)) )
>>          (mapc (lambda (item)
>>                  (when (,pred item)
>>                    (nconc ,r (cons item nil))))
>>                ,list)
>>          (cdr ,r))))
>> [...]
>> Why instead of '(nil) I get something else?
>
> Because nconc is destructively modifying its own source code.

I know that nconc destructive. But how this effect '(nil) in defmacro inside
`(...)?

-- 
Best regards!




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

* Re: "defmacro" and "local variables" and "let" and "nconc" strange behaviour...
  2013-01-13 15:00   ` Oleksandr Gavenko
@ 2013-01-13 16:45     ` Le Wang
  2013-01-13 17:25       ` Oleksandr Gavenko
  0 siblings, 1 reply; 7+ messages in thread
From: Le Wang @ 2013-01-13 16:45 UTC (permalink / raw)
  To: Oleksandr Gavenko; +Cc: help-gnu-emacs

On Sun, Jan 13, 2013 at 11:00 PM, Oleksandr Gavenko <gavenkoa@gmail.com> wrote:
> On 2013-01-13, Barry Margolin wrote:
>
>> In article <mailman.17290.1358086558.855.help-gnu-emacs@gnu.org>,
>>  Oleksandr Gavenko <gavenkoa@gmail.com> wrote:
>>
>>> I wrote simple macro:
>>>
>>>   (defmacro my-filter (pred list)
>>>     "Construct list with elements from LIST which satisfy PRED."
>>>     (let ( (r (make-symbol "r_")) )
>>>       `(let ( (,r '(nil)) )
>>>          (mapc (lambda (item)
>>>                  (when (,pred item)
>>>                    (nconc ,r (cons item nil))))
>>>                ,list)
>>>          (cdr ,r))))
>>> [...]
>>> Why instead of '(nil) I get something else?
>>
>> Because nconc is destructively modifying its own source code.
>
> I know that nconc destructive. But how this effect '(nil) in defmacro inside
> `(...)?

In lisp, code is data.  See my enlightenment process:
http://comments.gmane.org/gmane.emacs.bugs/50783

-- 
Le



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

* Re: "defmacro" and "local variables" and "let" and "nconc" strange behaviour...
  2013-01-13 16:45     ` Le Wang
@ 2013-01-13 17:25       ` Oleksandr Gavenko
  0 siblings, 0 replies; 7+ messages in thread
From: Oleksandr Gavenko @ 2013-01-13 17:25 UTC (permalink / raw)
  To: help-gnu-emacs

On 2013-01-13, Le Wang wrote:

> On Sun, Jan 13, 2013 at 11:00 PM, Oleksandr Gavenko <gavenkoa@gmail.com> wrote:
>> On 2013-01-13, Barry Margolin wrote:
>>
>>> In article <mailman.17290.1358086558.855.help-gnu-emacs@gnu.org>,
>>>  Oleksandr Gavenko <gavenkoa@gmail.com> wrote:
>>>
>>>> I wrote simple macro:
>>>>
>>>>   (defmacro my-filter (pred list)
>>>>     "Construct list with elements from LIST which satisfy PRED."
>>>>     (let ( (r (make-symbol "r_")) )
>>>>       `(let ( (,r '(nil)) )
>>>>          (mapc (lambda (item)
>>>>                  (when (,pred item)
>>>>                    (nconc ,r (cons item nil))))
>>>>                ,list)
>>>>          (cdr ,r))))
>>>> [...]
>>>> Why instead of '(nil) I get something else?
>>>
>>> Because nconc is destructively modifying its own source code.
>>
>> I know that nconc destructive. But how this effect '(nil) in defmacro inside
>> `(...)?
>
> In lisp, code is data.  See my enlightenment process:
> http://comments.gmane.org/gmane.emacs.bugs/50783

I follow you link and found different explanation from Drew Adams:

> Note that different Lisps (and different implementations of the same Lisp) can
> treat a sexp such as '(a b) differently - they might or might not create a new
> list each time it is read or eval'd.

> To be sure to get what you expect in situations like this, do not use '(...).
> Use `cons' or `list' or equivalent backquote syntax.  Do not expect '(...) to
> create new list structure each time it is read/eval'd.

That's why my code fail with '(nil)...

-- 
Best regards!




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

* Re: "defmacro" and "local variables" and "let" and "nconc" strange behaviour...
       [not found] ` <mailman.17291.1358086805.855.help-gnu-emacs@gnu.org>
@ 2013-01-14  9:04   ` jack-mac
  0 siblings, 0 replies; 7+ messages in thread
From: jack-mac @ 2013-01-14  9:04 UTC (permalink / raw)
  To: gnu.emacs.help; +Cc: help-gnu-emacs

Le dimanche 13 janvier 2013 15:18:46 UTC+1, Oleksandr Gavenko a écrit :
> On 2013-01-13, Oleksandr Gavenko wrote:
> 
> 
> 
> > I wrote simple macro:
> 
> >
> 
> >   (defmacro my-filter (pred list)
> 
> >     "Construct list with elements from LIST which satisfy PRED."
> 
> >     (let ( (r (make-symbol "r_")) )
> 
> >       `(let ( (,r '(nil)) )
> 
> >          (mapc (lambda (item)
> 
> >                  (when (,pred item)
> 
> >                    (nconc ,r (cons item nil))))
> 
> >                ,list)
> 
> >          (cdr ,r))))
> 
> >
> 
> > When I evaluate several times:
> 
> >
> 
> >   (my-filter (lambda (x) x) '(1 nil "a"))
> 
> >
> 
> > I get sequentially:
> 
> >
> 
> >   (1 "a")
> 
> >   (1 "a" 1 "a")
> 
> >   (1 "a" 1 "a" 1 "a")
> 
> >   (1 "a" 1 "a" 1 "a" 1 "a")
> 
> >
> 
> > When I eval:
> 
> >
> 
> >   (pp (macroexpand '(my-filter (lambda (x) x) '(1 nil "a"))))
> 
> >
> 
> > I get:
> 
> >
> 
> >   (let
> 
> >       ((r_
> 
> >         '(nil 1 "a" 1 "a" 1 "a" 1 "a" 1 "a" 1 "a" 1 "a" 1 "a")))
> 
> >     (mapc
> 
> >      (lambda
> 
> >        (item)
> 
> >        (when
> 
> >            ((lambda
> 
> >               (x)
> 
> >               x)
> 
> >             item)
> 
> >          (nconc r_
> 
> >                 (cons item nil))))
> 
> >      '(1 nil "a"))
> 
> >     (cdr r_))
> 
> >
> 
> > Why instead of '(nil) I get something else?
> 
> 
> 
> I found fix by changing '(nil) to (list nil). Please explain why first variant
> 
> fail?
> 
> 
> 
> -- 
> 
> Best regards!

To understand it, just try:
(defun foo (x)
  (let ((l '(0)))
    (nconc l (list x))))
(foo 1)
(foo 2)
This looks like a closure!



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

end of thread, other threads:[~2013-01-14  9:04 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-13 14:15 "defmacro" and "local variables" and "let" and "nconc" strange behaviour Oleksandr Gavenko
2013-01-13 14:18 ` Oleksandr Gavenko
     [not found] ` <mailman.17291.1358086805.855.help-gnu-emacs@gnu.org>
2013-01-14  9:04   ` jack-mac
     [not found] <mailman.17290.1358086558.855.help-gnu-emacs@gnu.org>
2013-01-13 14:21 ` Barry Margolin
2013-01-13 15:00   ` Oleksandr Gavenko
2013-01-13 16:45     ` Le Wang
2013-01-13 17:25       ` Oleksandr Gavenko

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).