help-gnu-emacs
[Top][All Lists]
Advanced

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

Re: Lexical binding and macros.


From: Pascal J. Bourguignon
Subject: Re: Lexical binding and macros.
Date: Wed, 15 Dec 2010 18:37:12 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux)

David Kastrup <dak@gnu.org> writes:

> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
>>> Do they still leak memory?  From http://c2.com/cgi/wiki?EmacsLisp :
>>
>>> "Note that variables bound with lexical-let are never released, even
>>> if they are never used. Try
>>
>>>  (loop for i from 1 to 100000 collect (lexical-let ((x i)) '()))
>>
>>> and watch it eat memory. So making infinity (ZeroOneInfinity) lexical
>>> variables is out of the question except for very small values of
>>> infinity."
>>
>> Additionally to what Pascal already explained, I'll add that,
>> lexical-let, like `loop' are relatively heavy macros, so you definitely
>> don't want to run them interpreted (where the macro is re-expanded each
>> time).
>
> Why would they be reexpanded each time?  They are macros.  Their
> expansion is done once and merely evalled each time.
>
> Or do I misunderstand something here?


In the case of Common Lisp, implementations providing an interpreter are
allowed to macro expand everytime.  Most implementations do cache the
expansion however.  (A lot of CL implementations just compile everything
automatically anyways).

For example, clisp performs the macroexpansions when defining the
function, and one time again when compiling it:


CL-USER> (defmacro m (x)
           (format t "(m ~S) is expanded" x)
           `(list ',x ',x))
M
CL-USER> (defun f ()
           (m 1))
(m 1) is expanded
F
CL-USER> (list (f) (f) (f))

((1 1) (1 1) (1 1))
CL-USER> (compile 'f)
(m 1) is expanded
F
NIL
NIL
CL-USER> 


In the case of emacs 23.2.1,

    (defmacro m (x)
      (message "(m %S) is expanded" x)
      `(list ',x ',x))

    (defun f ()
      (m 1))

    (list (f) (f) (f)) --> ((1 1) (1 1) (1 1))

produces in *Messages*:

    (m 1) is expanded [3 times]

So it looks like the emacs lisp interpreter doesn't not cache the macro
expansions.

emacs lisp expands it once more when compiling the function too:
(byte-compile 'f) --> #[nil "\300\211D\207" [1] 2]
*Messages*: (m 1) is expanded

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
A bad day in () is better than a good day in {}.


reply via email to

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