Mercurial > hg > xemacs-beta
diff man/cl.texi @ 5566:4654c01af32b
Improve the implementation, documentation of #'labels, #'flet.
lisp/ChangeLog addition:
2011-09-07 Aidan Kehoe <kehoea@parhasard.net>
* bytecomp.el:
* bytecomp.el (for-effect): Move this earlier in the file, it's
referenced in byte-compile-initial-macro-environment.
* bytecomp.el (byte-compile-initial-macro-environment):
In the byte-compile-macro-environment definition for #'labels, put
off the compiling the lambda bodies until the point where the rest
of the form is being compiled, allowing the lambda bodies to
access appropriate values for byte-compile-bound-variables, and
reducing excessive warning about free variables.
Add a byte-compile-macro-environment definition for #'flet. This
modifies byte-compile-function-environment appropriately, and
warns about bindings of functions that have macro definitions in
the current environment, about functions that have byte codes, and
about functions that have byte-compile methods (which may not do
what the user wants at runtime).
* bytecomp.el (byte-compile-funcall):
If FUNCTION is constant, call #'byte-compile-callargs-warn if
that's appropriate, giving warnings about problems with calling
functions bound with #'labels.
* cl-macs.el:
* cl-macs.el (flet):
Mention the main difference from Common Lisp, that the bindings
are dynamic, not lexical. Counsel the use of #'labels, not #'flet,
for this and other reasons. Explain the limited single use case for
#'flet. Cross-reference to bytecomp.el in a comment.
* cl-macs.el (labels):
Go into detail on which functions may be called from
where. Explain how to access the function definition of a label
within FORM. Add a comment cross-referencing to bytecomp.el.
man/ChangeLog addition:
2011-09-07 Aidan Kehoe <kehoea@parhasard.net>
* cl.texi (Function Bindings):
Move #'labels first, describe it in more detail, explaining that
it is to be preferred over #'flet, and explaining why.
Explain that dynamic bindings with #'flet will also not work when
functions are accessed through their bytecodes.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Wed, 07 Sep 2011 16:26:45 +0100 |
parents | a46c5c8d6564 |
children | bd80d9103fc8 |
line wrap: on
line diff
--- a/man/cl.texi Tue Sep 06 11:44:50 2011 +0100 +++ b/man/cl.texi Wed Sep 07 16:26:45 2011 +0100 @@ -1799,55 +1799,73 @@ @subsection Function Bindings @noindent -These forms make @code{let}-like bindings to functions instead -of variables. +These forms make @code{let}-like bindings to functions instead of +variables. Normally you should use @code{labels}, it is less expensive in +compiled code and avoids the problems of dynamic scope. + +@defmac labels (bindings@dots{}) forms@dots{} +This form establishes @code{lexical-let}-style bindings on the function cells +of symbols rather than on their value cells. Each @var{binding} must be a +list of the form @samp{(@var{name} @var{arglist} @var{forms}@dots{})}, which +defines a function exactly as if it were a @code{defun*} form. The function +@var{name} is available within @var{forms}, within the body of @var{name}, and +within the body of any other functions in @var{bindings}. This allows the +establishment of recursive and mutually-referential functions. + +These functions are not available by name at run-time to code textually +outside of the @code{labels} form, though they may be passed to other code by +value. Since @code{labels} makes lexical rather than dynamic bindings, +bindings of functions like @code{+} and @code{list} that have byte codes will +succeed---that is, calls to such functions within @var{form} will reflect the +bindings within the @code{labels} form, something not true of @code{flet}, +which see. + +Within @var{forms}, to access a bound function as a callable object, quote its +name using @var{#'name}, as in the following example. + +@example +(labels ((1+ (number) + "Return 1.0 added to NUMBER" + (+ number 1.0))) + (map 'vector #'1+ '(10 9 8 7 6 5 4 3 2 1))) + @result{} [11.0 10.0 9.0 8.0 7.0 6.0 5.0 4.0 3.0 2.0] +@end example + +Functions defined by @code{labels} may use the full Common Lisp argument +notation supported by @code{defun*}; also, the function body is enclosed in an +implicit block as if by @code{defun*}. @xref{Program Structure}. +@end defmac @defmac flet (bindings@dots{}) forms@dots{} -This form establishes @code{let}-style bindings on the function -cells of symbols rather than on the value cells. Each @var{binding} -must be a list of the form @samp{(@var{name} @var{arglist} -@var{forms}@dots{})}, which defines a function exactly as if -it were a @code{defun*} form. The function @var{name} is defined -accordingly for the duration of the body of the @code{flet}; then -the old function definition, or lack thereof, is restored. - -While @code{flet} in Common Lisp establishes a lexical binding of -@var{name}, Emacs Lisp @code{flet} makes a dynamic binding. The -result is that @code{flet} affects indirect calls to a function as -well as calls directly inside the @code{flet} form itself. - -You can use @code{flet} to disable or modify the behavior of a -function in a temporary fashion. This will even work on Emacs -primitives, although note that some calls to primitive functions -internal to Emacs are made without going through the symbol's -function cell, and so will not be affected by @code{flet}. For -example, +This form establishes @code{let}-style bindings on the function cells of +symbols rather than on the value cells. In contravention of Common Lisp, +Emacs Lisp @code{flet} establishes dynamic bindings (available at runtime) +rather than lexical (available at compile time, but outside of @var{forms}, +not at runtime). The result is that @code{flet} affects indirect calls to a +function as well as calls directly inside the @code{flet} form itself. + +You can use @code{flet} to disable or modify the behavior of a function in a +temporary fashion. This will even work on XEmacs primitives, although note +that some calls to primitive functions internal to XEmacs are made without +going through the symbol's function cell, and so will not be affected by +@code{flet}. For example, @example (flet ((message (&rest args) (push args saved-msgs))) (do-something)) @end example -This code attempts to replace the built-in function @code{message} -with a function that simply saves the messages in a list rather -than displaying them. The original definition of @code{message} -will be restored after @code{do-something} exits. This code will -work fine on messages generated by other Lisp code, but messages -generated directly inside Emacs will not be caught since they make -direct C-language calls to the message routines rather than going -through the Lisp @code{message} function. - -Functions defined by @code{flet} may use the full Common Lisp -argument notation supported by @code{defun*}; also, the function -body is enclosed in an implicit block as if by @code{defun*}. -@xref{Program Structure}. -@end defmac - -@defmac labels (bindings@dots{}) forms@dots{} -The @code{labels} form is a synonym for @code{flet}. (In Common -Lisp, @code{labels} and @code{flet} differ in ways that depend on -their lexical scoping; these distinctions vanish in dynamically -scoped Emacs Lisp.) +This code attempts to replace the built-in function @code{message} with a +function that simply saves the messages in a list rather than displaying them. +The original definition of @code{message} will be restored after +@code{do-something} exits. This code will work fine on messages generated by +other Lisp code, but messages generated directly inside XEmacs will not be +caught since they make direct C-language calls to the message routines rather +than going through the Lisp @code{message} function. + +This is equally true for functions with associated byte codes, since they are +also not accessed through the Lisp function slot. The byte compiler will +warn in both these cases. @end defmac @node Macro Bindings, , Function Bindings, Variable Bindings