summaryrefslogtreecommitdiff
path: root/doc/misc/cl.texi
diff options
context:
space:
mode:
Diffstat (limited to 'doc/misc/cl.texi')
-rw-r--r--doc/misc/cl.texi174
1 files changed, 95 insertions, 79 deletions
diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi
index 4eb3d85d2ba..a6747b1096a 100644
--- a/doc/misc/cl.texi
+++ b/doc/misc/cl.texi
@@ -444,7 +444,7 @@ the ``rest'' argument is bound to the keyword list as it appears
in the call. For example:
@example
-(cl-defun find-thing (thing &rest rest &key need &allow-other-keys)
+(cl-defun find-thing (thing thing-list &rest rest &key need &allow-other-keys)
(or (apply 'cl-member thing thing-list :allow-other-keys t rest)
(if need (error "Thing not found"))))
@end example
@@ -843,6 +843,7 @@ constructs.
* Iteration:: @code{cl-do}, @code{cl-dotimes}, @code{cl-dolist}, @code{cl-do-symbols}.
* Loop Facility:: The Common Lisp @code{loop} macro.
* Multiple Values:: @code{cl-values}, @code{cl-multiple-value-bind}, etc.
+* Macro-Writing Macros:: @code{cl-with-gensyms}, @code{cl-once-only}.
@end menu
@node Assignment
@@ -919,69 +920,6 @@ cl-caaar@dots{}cl-cddddr cl-first@dots{}cl-tenth
Note that for @code{cl-getf} (as for @code{nthcdr}), the list argument
of the function must itself be a valid @var{place} form.
-@item
-General Emacs Lisp functions:
-@example
-buffer-file-name getenv
-buffer-modified-p global-key-binding
-buffer-name local-key-binding
-buffer-string mark
-buffer-substring mark-marker
-current-buffer marker-position
-current-case-table mouse-position
-current-column point
-current-global-map point-marker
-current-input-mode point-max
-current-local-map point-min
-current-window-configuration read-mouse-position
-default-file-modes screen-height
-documentation-property screen-width
-face-background selected-window
-face-background-pixmap selected-screen
-face-font selected-frame
-face-foreground standard-case-table
-face-underline-p syntax-table
-file-modes visited-file-modtime
-frame-height window-height
-frame-parameters window-width
-frame-visible-p x-get-secondary-selection
-frame-width x-get-selection
-get-register
-@end example
-
-Most of these have directly corresponding ``set'' functions, like
-@code{use-local-map} for @code{current-local-map}, or @code{goto-char}
-for @code{point}. A few, like @code{point-min}, expand to longer
-sequences of code when they are used with @code{setf}
-(@code{(narrow-to-region x (point-max))} in this case).
-
-@item
-A call of the form @code{(substring @var{subplace} @var{n} [@var{m}])},
-where @var{subplace} is itself a valid generalized variable whose
-current value is a string, and where the value stored is also a
-string. The new string is spliced into the specified part of the
-destination string. For example:
-
-@example
-(setq a (list "hello" "world"))
- @result{} ("hello" "world")
-(cadr a)
- @result{} "world"
-(substring (cadr a) 2 4)
- @result{} "rl"
-(setf (substring (cadr a) 2 4) "o")
- @result{} "o"
-(cadr a)
- @result{} "wood"
-a
- @result{} ("hello" "wood")
-@end example
-
-The generalized variable @code{buffer-substring}, listed above,
-also works in this way by replacing a portion of the current buffer.
-
-@c FIXME? Also 'eq'? (see cl-lib.el)
-
@c Currently commented out in cl.el.
@ignore
@item
@@ -1245,6 +1183,12 @@ blocks for other macros like @code{cl-incf}, and @code{cl-pushnew}.
The @code{cl-letf} and @code{cl-letf*} macros are used in the processing
of symbol macros; @pxref{Macro Bindings}.
+@defmac with-memoization @var{place} @var{code}@dots{}
+This macro provides a simple way to do memoization. @var{code} is
+evaluated and then stashed in @var{place}. If @var{place}'s value is
+non-@code{nil}, return that value instead of evaluating @var{code}.
+@end defmac
+
@node Variable Bindings
@section Variable Bindings
@@ -1374,19 +1318,10 @@ bar
A @code{setq} of a symbol macro is treated the same as a @code{setf}.
I.e., @code{(setq foo 4)} in the above would be equivalent to
-@code{(setf foo 4)}, which in turn expands to @code{(setf (car bar) 4)}.
-
-Likewise, a @code{let} or @code{let*} binding a symbol macro is
-treated like a @code{cl-letf} or @code{cl-letf*}. This differs from true
-Common Lisp, where the rules of lexical scoping cause a @code{let}
-binding to shadow a @code{symbol-macrolet} binding. In this package,
-such shadowing does not occur, even when @code{lexical-binding} is
-@c See https://debbugs.gnu.org/12119
-@code{t}. (This behavior predates the addition of lexical binding to
-Emacs Lisp, and may change in future to respect @code{lexical-binding}.)
-At present in this package, only @code{lexical-let} and
-@code{lexical-let*} will shadow a symbol macro. @xref{Obsolete
-Lexical Binding}.
+@code{(setf foo 4)}, which in turn expands to @code{(setf (car bar)
+4)}. A @code{let} (or @code{let*}, @code{lambda}, ...) binding of
+the same symbol will locally shadow the symbol macro as is the case in
+Common Lisp.
There is no analogue of @code{defmacro} for symbol macros; all symbol
macros are local. A typical use of @code{cl-symbol-macrolet} is in the
@@ -2507,6 +2442,86 @@ in @code{cl-multiple-value-bind}.
Since a perfect emulation is not feasible in Emacs Lisp, this
package opts to keep it as simple and predictable as possible.
+@node Macro-Writing Macros
+@section Macro-Writing Macros
+
+@noindent
+This package includes two classic Common Lisp macro-writing macros to
+help render complex macrology easier to read.
+
+@defmac cl-with-gensyms names@dots{} body
+This macro expands to code that executes @var{body} with each of the
+variables in @var{names} bound to a fresh uninterned symbol, or
+@dfn{gensym}, in Common Lisp parlance. For macros requiring more than
+one gensym, use of @code{cl-with-gensyms} shortens the code and
+renders one's intentions clearer. Compare:
+
+@example
+(defmacro my-macro (foo)
+ (let ((bar (gensym "bar"))
+ (baz (gensym "baz"))
+ (quux (gensym "quux")))
+ `(let ((,bar (+ @dots{})))
+ @dots{})))
+
+(defmacro my-macro (foo)
+ (cl-with-gensyms (bar baz quux)
+ `(let ((,bar (+ @dots{})))
+ @dots{})))
+@end example
+@end defmac
+
+@defmac cl-once-only ((variable form)@dots{}) body
+This macro is primarily to help the macro programmer ensure that forms
+supplied by the user of the macro are evaluated just once by its
+expansion even though the result of evaluating the form is to occur
+more than once. Less often, this macro is used to ensure that forms
+supplied by the macro programmer are evaluated just once.
+
+Each @var{variable} may be used to refer to the result of evaluating
+@var{form} in @var{body}. @code{cl-once-only} binds each
+@var{variable} to a fresh uninterned symbol during the evaluation of
+@var{body}. Then, @code{cl-once-only} wraps the final expansion in
+code to evaluate each @var{form} and bind the result to the
+corresponding uninterned symbol. Thus, when the macro writer
+substitutes the value for @var{variable} into the expansion they are
+effectively referring to the result of evaluating @var{form}, rather
+than @var{form} itself. Another way to put this is that each
+@var{variable} is bound to an expression for the (singular) result of
+evaluating @var{form}.
+
+The most common case is where @var{variable} is one of the arguments
+to the macro being written, so @code{(variable variable)} may be
+abbreviated to just @code{variable}.
+
+For example, consider this macro:
+
+@example
+(defmacro my-list (x y &rest forms)
+ (let ((x-result (gensym))
+ (y-result (gensym)))
+ `(let ((,x-result ,x)
+ (,y-result ,y))
+ (list ,x-result ,y-result ,x-result ,y-result
+ (progn ,@@forms))))
+@end example
+
+In a call like @w{@code{(my-list (pop foo) @dots{})}} the intermediate
+binding to @code{x-result} ensures that the @code{pop} is not done
+twice. But as a result the code is rather complex: the reader must
+keep track of how @code{x-result} really just means the first
+parameter of the call to the macro, and the required use of multiple
+gensyms to avoid variable capture by @code{(progn ,@@forms)} obscures
+things further. @code{cl-once-only} takes care of these details:
+
+@example
+(defmacro my-list (x y &rest forms)
+ (cl-once-only (x y)
+ `(list ,x ,y ,x ,y
+ (progn ,@@forms))))
+@end example
+@end defmac
+
@node Macros
@chapter Macros
@@ -2862,6 +2877,7 @@ out the property and value cells.
@node Creating Symbols
@section Creating Symbols
+@cindex gensym
@noindent
These functions create unique symbols, typically for use as
@@ -5014,13 +5030,13 @@ The above @code{incf} example could be written using
@example
(defmacro incf (place &optional n)
(gv-letplace (getter setter) place
- (macroexp-let2 nil v (or n 1)
+ (cl-once-only ((v (or n 1)))
(funcall setter `(+ ,v ,getter)))))
@end example
@ignore
(defmacro concatf (place &rest args)
(gv-letplace (getter setter) place
- (macroexp-let2 nil v (mapconcat 'identity args "")
+ (cl-once-only ((v `(mapconcat 'identity ',args)))
(funcall setter `(concat ,getter ,v)))))
@end ignore
@end defmac