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

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

[h-e-w] info


From: David R
Subject: [h-e-w] info
Date: Mon, 31 Mar 2008 23:39:11 +0100
User-agent: Thunderbird 1.5.0.14 (Windows/20071210)

File: elisp, Node: Surprising Local Vars, Next: Eval During Expansion, Prev: Argument Evaluation, Up: Problems with Macros

13.6.3 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
^^^^^
tempvar

expansion instead of the usual interned symbol `max' that appears in
expressions ordinarily.


File: elisp, Node: Compiling Macros, Next: Defining Macros, Prev: Expansion, Up: Macros

13.3 Macros and Byte Compilation
================================

You might ask why we take the trouble to compute an expansion for a
macro and then evaluate the expansion.  Why not have the macro body
produce the desired results directly?  The reason has to do with
compilation.

  When a macro call appears in a Lisp program being compiled, the Lisp
compiler calls the macro definition just as the interpreter would, and
receives an expansion.  But instead of evaluating this expansion, it
compiles the expansion as if it had appeared directly in the program.
As a result, the compiled code produces the value and side effects
                                         ^^^^^ value of what?

intended for the macro, but executes at full compiled speed.  This would
    ^^^ as the expansion of the macro, or passed to the macro?

not work if the macro body computed the value and side effects
                            ^^^^^^^^ computed = evaluated or expanded?

itself--they would be computed at compile time, which is not useful.
                  ^^^^^^^^

  In order for compilation of macro calls to work, the macros must
already be defined in Lisp when the calls to them are compiled.  The
compiler has a special feature to help you do this: if a file being
compiled contains a `defmacro' form, the macro is defined temporarily
for the rest of the compilation of that file.  To make this feature
work, you must put the `defmacro' in the same file where it is used,
and before its first use.

  Byte-compiling a file executes any `require' calls at top-level in
the file.  This is in case the file needs the required packages for
proper compilation.  One way to ensure that necessary macro definitions
are available during compilation is to require the files that define
them (*note Named Features::).  To avoid loading the macro definition
files when someone _runs_ the compiled program, write
`eval-when-compile' around the `require' calls (*note Eval During
Compile::).






In GNU Emacs 22.0.990.1 (i386-mingw-nt5.1.2600)
of 2007-05-23 on LENNART-69DE564 (patched)
Windowing system distributor `Microsoft Corp.', version 5.1.2600
configured using `configure --with-gcc (3.4) --cflags -Ic:/g/include'

Important settings:
value of $LC_ALL: nil
value of $LC_COLLATE: nil
value of $LC_CTYPE: nil
value of $LC_MESSAGES: nil
value of $LC_MONETARY: nil
value of $LC_NUMERIC: nil
value of $LC_TIME: nil
value of $LANG: ENG
locale-coding-system: cp1252
default-enable-multibyte-characters: t

Major mode: Info

Minor modes in effect:
server-mode: t
show-paren-mode: t
encoded-kbd-mode: t
tooltip-mode: t
tool-bar-mode: t
mouse-wheel-mode: t
noticeable-minibuffer-prompts-mode: t
menu-bar-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
blink-cursor-mode: t
unify-8859-on-encoding-mode: t
utf-translate-cjk-mode: t
auto-compression-mode: t
line-number-mode: t
transient-mark-mode: t

Recent input:
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1> <mouse-1>
<mouse-1> SPC <help-echo> <mouse-1> <mouse-1> [ SPC
] <down-mouse-1> <mouse-1> <down> <right> <down> <up>
<up> <down> <down> <left> <left> <left> <left> <right>
<right> <left> <right> <left> <down> <down> <down>
<down> <down> <down> <down> <down> <down> <down> <down>
<down> <down> <down> <down> <down> <down> <down> <down>
<down> <down> <up> <up> <up> <up> <up> <down> <up>
<right> <right> <right> <right> <right> <right> <right>
<right> <right> <right> <right> <left> <down> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <down>
[ SPC ] SPC <up> <down> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <up> <up> <down> <down> <down>
<down> <down> <down> <down> <down> <down> <down> <down>
<down> <down> <down> <down> <down> <down> <down> <down>
<down> <up> <prior> <next> <up> <down-mouse-1> <mouse-movement>
<mouse-movement> <help-echo> <mouse-movement> <mouse-movement>
<mouse-movement> <mouse-movement> <drag-mouse-1> C-x
a <help-echo> <help-echo> <help-echo> M-w <help-echo>
<help-echo> <help-echo> <help-echo> <help-echo> <help-echo>
<help-echo> <help-echo> <help-echo> <help-echo> <help-echo>
<help-echo> <help-echo> <help-echo> <help-echo> <help-echo>
<help-echo> <help-echo> <help-echo> <help-echo> <help-echo>
<help-echo> <help-echo> <help-echo> <help-echo> <help-echo>
<help-echo> <help-echo> <help-echo> <help-echo> <help-echo>
<help-echo> <menu-bar> <help-menu> <report-emacs-b
ug>

Recent messages:
(No files need saving)
nil
call-interactively: End of buffer
call-interactively: Beginning of buffer
Mark set [2 times]
(2 3)
(1 2 3 4 2 3) [2 times]
(1 (2 3) 4 (2 3))
(2 3)
Loading emacsbug...done
*** E-Mail body has been placed on clipboard, please paste them here! ***




reply via email to

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