GNU Info

Info Node: (elisp)Surprising Local Vars

(elisp)Surprising Local Vars


Next: Eval During Expansion Prev: Argument Evaluation Up: Problems with Macros
Enter node , (file) or (file)node

Local Variables in Macro Expansions
-----------------------------------

   In the previous section, the definition of `for' was fixed as
follows to make the expansion evaluate the macro arguments the proper
number of times:

     (defmacro for (var from init to final do &rest body)
       "Execute a simple for loop: (for i from 1 to 10 do (print i))."
       `(let ((,var ,init)
              (max ,final))
          (while (<= ,var max)
            ,@body
            (inc ,var))))

   The new definition of `for' has a new problem: it introduces a local
variable named `max' which the user does not expect.  This causes
trouble in examples such as the following:

     (let ((max 0))
       (for x from 0 to 10 do
         (let ((this (frob x)))
           (if (< max this)
               (setq max this)))))

The references to `max' inside the body of the `for', which are
supposed to refer to the user's binding of `max', really access the
binding made by `for'.

   The way to correct this is to use an uninterned symbol instead of
`max' (Note: Creating Symbols).  The uninterned symbol can be bound
and referred to just like any other symbol, but since it is created by
`for', we know that it cannot already appear in the user's program.
Since it is not interned, there is no way the user can put it into the
program later.  It will never appear anywhere except where put by
`for'.  Here is a definition of `for' that works this way:

     (defmacro for (var from init to final do &rest body)
       "Execute a simple for loop: (for i from 1 to 10 do (print i))."
       (let ((tempvar (make-symbol "max")))
         `(let ((,var ,init)
                (,tempvar ,final))
            (while (<= ,var ,tempvar)
              ,@body
              (inc ,var)))))

This creates an uninterned symbol named `max' and puts it in the
expansion instead of the usual interned symbol `max' that appears in
expressions ordinarily.


automatically generated by info2www version 1.2.2.9