diff options
| author | Stefan Kangas | 2025-02-22 17:32:31 +0100 |
|---|---|---|
| committer | Stefan Kangas | 2025-02-23 00:38:22 +0100 |
| commit | 95fee880e45184f4820e9704b75887ef2d91bd01 (patch) | |
| tree | 09afd4a8d6f9ccf0f2cec36e4f604deaf040c728 | |
| parent | 44a1c4a9aea54d6542bcf0c231b080f0ed023229 (diff) | |
| download | emacs-95fee880e45184f4820e9704b75887ef2d91bd01.tar.gz emacs-95fee880e45184f4820e9704b75887ef2d91bd01.zip | |
New macros incf and decf
* lisp/emacs-lisp/cl-lib.el (cl-incf, cl-decf): Move macros from here...
* lisp/emacs-lisp/gv.el (incf, decf): ...to here. Make old names into
aliases, documented as deprecated.
* lisp/obsolete/cl.el: Don't alias incf and decf.
* test/lisp/emacs-lisp/cl-lib-tests.el (cl-lib-test-incf)
(cl-lib-test-decf): Move tests from here...
* test/lisp/emacs-lisp/gv-tests.el (gv-incf, gv-decf): ...to here.
* doc/lispref/numbers.texi (Arithmetic Operations):
* lisp/emacs-lisp/shortdoc.el (number): Document incf and decf.
* doc/lispref/variables.texi (Multisession Variables):
* doc/misc/cl.texi (Organization, Modify Macros, Modify Macros)
(Modify Macros, Macro Bindings, For Clauses, Property Lists)
(Structures, Efficiency Concerns, Obsolete Setf Customization): Delete
cl-incf and cl-decf documentation, moving any relevant parts to lispref.
Delete some parts that seem to primarily regard implementation details
that do not warrant inclusion in lispref. Update all examples to use
incf/decf.
| -rw-r--r-- | doc/lispref/numbers.texi | 19 | ||||
| -rw-r--r-- | doc/lispref/variables.texi | 2 | ||||
| -rw-r--r-- | doc/misc/cl.texi | 112 | ||||
| -rw-r--r-- | etc/NEWS | 23 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl-lib.el | 22 | ||||
| -rw-r--r-- | lisp/emacs-lisp/gv.el | 32 | ||||
| -rw-r--r-- | lisp/emacs-lisp/shortdoc.el | 12 | ||||
| -rw-r--r-- | lisp/obsolete/cl.el | 2 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/cl-lib-tests.el | 36 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/gv-tests.el | 36 |
10 files changed, 135 insertions, 161 deletions
diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi index 17fa1e05fee..29105959ecd 100644 --- a/doc/lispref/numbers.texi +++ b/doc/lispref/numbers.texi | |||
| @@ -668,8 +668,8 @@ foo | |||
| 668 | @result{} 4 | 668 | @result{} 4 |
| 669 | @end example | 669 | @end example |
| 670 | 670 | ||
| 671 | If you want to increment the variable, you must use @code{setq}, | 671 | If you want to increment the variable, you must use @code{setq} (or |
| 672 | like this: | 672 | @code{incf}), like this: |
| 673 | 673 | ||
| 674 | @example | 674 | @example |
| 675 | (setq foo (1+ foo)) | 675 | (setq foo (1+ foo)) |
| @@ -681,6 +681,21 @@ like this: | |||
| 681 | This function returns @var{number-or-marker} minus 1. | 681 | This function returns @var{number-or-marker} minus 1. |
| 682 | @end defun | 682 | @end defun |
| 683 | 683 | ||
| 684 | @defmac incf place &optional delta | ||
| 685 | This macro increments the number stored in @var{place} by one, or | ||
| 686 | by @var{delta} if specified. The incremented value is returned. | ||
| 687 | |||
| 688 | @var{place} can be a symbol or a generalized variable, @xref{Generalized | ||
| 689 | Variables}. For example, @code{(incf i)} is equivalent to | ||
| 690 | @code{(setq i (1+ i))}, and @code{(incf (car x) 2)} is equivalent to | ||
| 691 | @code{(setcar x (+ (car x) 2))}. | ||
| 692 | @end defmac | ||
| 693 | |||
| 694 | @defmac decf place &optional delta | ||
| 695 | This macro decrements the number stored in @var{place} by one, or | ||
| 696 | by @var{delta} if specified. The decremented value is returned. | ||
| 697 | @end defmac | ||
| 698 | |||
| 684 | @defun + &rest numbers-or-markers | 699 | @defun + &rest numbers-or-markers |
| 685 | This function adds its arguments together. When given no arguments, | 700 | This function adds its arguments together. When given no arguments, |
| 686 | @code{+} returns 0. | 701 | @code{+} returns 0. |
diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi index 998a74d067a..46027edb041 100644 --- a/doc/lispref/variables.texi +++ b/doc/lispref/variables.texi | |||
| @@ -3130,7 +3130,7 @@ If the multisession variable is synchronized, setting it may update | |||
| 3130 | the value first. For instance: | 3130 | the value first. For instance: |
| 3131 | 3131 | ||
| 3132 | @lisp | 3132 | @lisp |
| 3133 | (cl-incf (multisession-value foo-bar)) | 3133 | (incf (multisession-value foo-bar)) |
| 3134 | @end lisp | 3134 | @end lisp |
| 3135 | 3135 | ||
| 3136 | This first checks whether the value has changed in a different | 3136 | This first checks whether the value has changed in a different |
diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi index f95900a085e..8fb308e64a5 100644 --- a/doc/misc/cl.texi +++ b/doc/misc/cl.texi | |||
| @@ -168,9 +168,6 @@ and information about the package. This file is relatively compact. | |||
| 168 | 168 | ||
| 169 | @item cl-extra.el | 169 | @item cl-extra.el |
| 170 | This file contains the larger, more complex or unusual functions. | 170 | This file contains the larger, more complex or unusual functions. |
| 171 | It is kept separate so that packages which only want to use Common | ||
| 172 | Lisp fundamentals like the @code{cl-incf} function won't need to pay | ||
| 173 | the overhead of loading the more advanced functions. | ||
| 174 | 171 | ||
| 175 | @item cl-seq.el | 172 | @item cl-seq.el |
| 176 | This file contains most of the advanced functions for operating | 173 | This file contains most of the advanced functions for operating |
| @@ -197,8 +194,8 @@ this package prior to Emacs 24.3. Nowadays, it is replaced by | |||
| 197 | but use different function names (in fact, @file{cl.el} mainly just | 194 | but use different function names (in fact, @file{cl.el} mainly just |
| 198 | defines aliases to the @file{cl-lib.el} definitions). Where | 195 | defines aliases to the @file{cl-lib.el} definitions). Where |
| 199 | @file{cl-lib.el} defines a function called, for example, | 196 | @file{cl-lib.el} defines a function called, for example, |
| 200 | @code{cl-incf}, @file{cl.el} uses the same name but without the | 197 | @code{cl-first}, @file{cl.el} uses the same name but without the |
| 201 | @samp{cl-} prefix, e.g., @code{incf} in this example. There are a few | 198 | @samp{cl-} prefix, e.g., @code{first} in this example. There are a few |
| 202 | exceptions to this. First, functions such as @code{cl-defun} where | 199 | exceptions to this. First, functions such as @code{cl-defun} where |
| 203 | the unprefixed version was already used for a standard Emacs Lisp | 200 | the unprefixed version was already used for a standard Emacs Lisp |
| 204 | function. In such cases, the @file{cl.el} version adds a @samp{*} | 201 | function. In such cases, the @file{cl.el} version adds a @samp{*} |
| @@ -1028,7 +1025,7 @@ generalized variables. | |||
| 1028 | 1025 | ||
| 1029 | @menu | 1026 | @menu |
| 1030 | * Setf Extensions:: Additional @code{setf} places. | 1027 | * Setf Extensions:: Additional @code{setf} places. |
| 1031 | * Modify Macros:: @code{cl-incf}, @code{cl-rotatef}, @code{cl-letf}, @code{cl-callf}, etc. | 1028 | * Modify Macros:: @code{cl-rotatef}, @code{cl-letf}, @code{cl-callf}, etc. |
| 1032 | @end menu | 1029 | @end menu |
| 1033 | 1030 | ||
| 1034 | @node Setf Extensions | 1031 | @node Setf Extensions |
| @@ -1085,52 +1082,6 @@ Specifically, all subforms are evaluated from left to right, then | |||
| 1085 | all the assignments are done (in an undefined order). | 1082 | all the assignments are done (in an undefined order). |
| 1086 | @end defmac | 1083 | @end defmac |
| 1087 | 1084 | ||
| 1088 | @defmac cl-incf place &optional x | ||
| 1089 | This macro increments the number stored in @var{place} by one, or | ||
| 1090 | by @var{x} if specified. The incremented value is returned. For | ||
| 1091 | example, @code{(cl-incf i)} is equivalent to @code{(setq i (1+ i))}, and | ||
| 1092 | @code{(cl-incf (car x) 2)} is equivalent to @code{(setcar x (+ (car x) 2))}. | ||
| 1093 | |||
| 1094 | As with @code{setf}, care is taken to preserve the ``apparent'' order | ||
| 1095 | of evaluation. For example, | ||
| 1096 | |||
| 1097 | @example | ||
| 1098 | (cl-incf (aref vec (cl-incf i))) | ||
| 1099 | @end example | ||
| 1100 | |||
| 1101 | @noindent | ||
| 1102 | appears to increment @code{i} once, then increment the element of | ||
| 1103 | @code{vec} addressed by @code{i}; this is indeed exactly what it | ||
| 1104 | does, which means the above form is @emph{not} equivalent to the | ||
| 1105 | ``obvious'' expansion, | ||
| 1106 | |||
| 1107 | @example | ||
| 1108 | (setf (aref vec (cl-incf i)) | ||
| 1109 | (1+ (aref vec (cl-incf i)))) ; wrong! | ||
| 1110 | @end example | ||
| 1111 | |||
| 1112 | @noindent | ||
| 1113 | but rather to something more like | ||
| 1114 | |||
| 1115 | @example | ||
| 1116 | (let ((temp (cl-incf i))) | ||
| 1117 | (setf (aref vec temp) (1+ (aref vec temp)))) | ||
| 1118 | @end example | ||
| 1119 | |||
| 1120 | @noindent | ||
| 1121 | Again, all of this is taken care of automatically by @code{cl-incf} and | ||
| 1122 | the other generalized-variable macros. | ||
| 1123 | |||
| 1124 | As a more Emacs-specific example of @code{cl-incf}, the expression | ||
| 1125 | @code{(cl-incf (point) @var{n})} is essentially equivalent to | ||
| 1126 | @code{(forward-char @var{n})}. | ||
| 1127 | @end defmac | ||
| 1128 | |||
| 1129 | @defmac cl-decf place &optional x | ||
| 1130 | This macro decrements the number stored in @var{place} by one, or | ||
| 1131 | by @var{x} if specified. | ||
| 1132 | @end defmac | ||
| 1133 | |||
| 1134 | @defmac cl-pushnew x place @t{&key :test :test-not :key} | 1085 | @defmac cl-pushnew x place @t{&key :test :test-not :key} |
| 1135 | This macro inserts @var{x} at the front of the list stored in | 1086 | This macro inserts @var{x} at the front of the list stored in |
| 1136 | @var{place}, but only if @var{x} isn't present in the list already. | 1087 | @var{place}, but only if @var{x} isn't present in the list already. |
| @@ -1243,8 +1194,8 @@ It does the bindings in sequential rather than parallel order. | |||
| 1243 | This is the ``generic'' modify macro. It calls @var{function}, | 1194 | This is the ``generic'' modify macro. It calls @var{function}, |
| 1244 | which should be an unquoted function name, macro name, or lambda. | 1195 | which should be an unquoted function name, macro name, or lambda. |
| 1245 | It passes @var{place} and @var{args} as arguments, and assigns the | 1196 | It passes @var{place} and @var{args} as arguments, and assigns the |
| 1246 | result back to @var{place}. For example, @code{(cl-incf @var{place} | 1197 | result back to @var{place}. For example, @code{(incf @var{place} |
| 1247 | @var{n})} is the same as @code{(cl-callf + @var{place} @var{n})}. | 1198 | @var{n})} could be implemented as @code{(cl-callf + @var{place} @var{n})}. |
| 1248 | Some more examples: | 1199 | Some more examples: |
| 1249 | 1200 | ||
| 1250 | @example | 1201 | @example |
| @@ -1264,7 +1215,7 @@ equivalent to @code{(cl-callf2 cons @var{x} @var{place})}. | |||
| 1264 | @end defmac | 1215 | @end defmac |
| 1265 | 1216 | ||
| 1266 | The @code{cl-callf} and @code{cl-callf2} macros serve as building | 1217 | The @code{cl-callf} and @code{cl-callf2} macros serve as building |
| 1267 | blocks for other macros like @code{cl-incf}, and @code{cl-pushnew}. | 1218 | blocks for other macros like @code{cl-pushnew}. |
| 1268 | The @code{cl-letf} and @code{cl-letf*} macros are used in the processing | 1219 | The @code{cl-letf} and @code{cl-letf*} macros are used in the processing |
| 1269 | of symbol macros; @pxref{Macro Bindings}. | 1220 | of symbol macros; @pxref{Macro Bindings}. |
| 1270 | 1221 | ||
| @@ -1401,7 +1352,7 @@ replaced by @var{expansion}. | |||
| 1401 | @example | 1352 | @example |
| 1402 | (setq bar '(5 . 9)) | 1353 | (setq bar '(5 . 9)) |
| 1403 | (cl-symbol-macrolet ((foo (car bar))) | 1354 | (cl-symbol-macrolet ((foo (car bar))) |
| 1404 | (cl-incf foo)) | 1355 | (incf foo)) |
| 1405 | bar | 1356 | bar |
| 1406 | @result{} (6 . 9) | 1357 | @result{} (6 . 9) |
| 1407 | @end example | 1358 | @end example |
| @@ -1426,7 +1377,7 @@ expansion of another macro: | |||
| 1426 | body)))) | 1377 | body)))) |
| 1427 | 1378 | ||
| 1428 | (setq mylist '(1 2 3 4)) | 1379 | (setq mylist '(1 2 3 4)) |
| 1429 | (my-dolist (x mylist) (cl-incf x)) | 1380 | (my-dolist (x mylist) (incf x)) |
| 1430 | mylist | 1381 | mylist |
| 1431 | @result{} (2 3 4 5) | 1382 | @result{} (2 3 4 5) |
| 1432 | @end example | 1383 | @end example |
| @@ -1440,14 +1391,14 @@ shown here expands to | |||
| 1440 | @example | 1391 | @example |
| 1441 | (cl-loop for G1234 on mylist do | 1392 | (cl-loop for G1234 on mylist do |
| 1442 | (cl-symbol-macrolet ((x (car G1234))) | 1393 | (cl-symbol-macrolet ((x (car G1234))) |
| 1443 | (cl-incf x))) | 1394 | (incf x))) |
| 1444 | @end example | 1395 | @end example |
| 1445 | 1396 | ||
| 1446 | @noindent | 1397 | @noindent |
| 1447 | which in turn expands to | 1398 | which in turn expands to |
| 1448 | 1399 | ||
| 1449 | @example | 1400 | @example |
| 1450 | (cl-loop for G1234 on mylist do (cl-incf (car G1234))) | 1401 | (cl-loop for G1234 on mylist do (incf (car G1234))) |
| 1451 | @end example | 1402 | @end example |
| 1452 | 1403 | ||
| 1453 | @xref{Loop Facility}, for a description of the @code{cl-loop} macro. | 1404 | @xref{Loop Facility}, for a description of the @code{cl-loop} macro. |
| @@ -1999,7 +1950,7 @@ a @code{setf}-able ``reference'' onto the elements of the list | |||
| 1999 | rather than just a temporary variable. For example, | 1950 | rather than just a temporary variable. For example, |
| 2000 | 1951 | ||
| 2001 | @example | 1952 | @example |
| 2002 | (cl-loop for x in-ref my-list do (cl-incf x)) | 1953 | (cl-loop for x in-ref my-list do (incf x)) |
| 2003 | @end example | 1954 | @end example |
| 2004 | 1955 | ||
| 2005 | @noindent | 1956 | @noindent |
| @@ -2940,7 +2891,7 @@ The @code{get} and @code{cl-get} functions are also @code{setf}-able. | |||
| 2940 | The fact that @code{default} is ignored can sometimes be useful: | 2891 | The fact that @code{default} is ignored can sometimes be useful: |
| 2941 | 2892 | ||
| 2942 | @example | 2893 | @example |
| 2943 | (cl-incf (cl-get 'foo 'usage-count 0)) | 2894 | (incf (cl-get 'foo 'usage-count 0)) |
| 2944 | @end example | 2895 | @end example |
| 2945 | 2896 | ||
| 2946 | Here, symbol @code{foo}'s @code{usage-count} property is incremented | 2897 | Here, symbol @code{foo}'s @code{usage-count} property is incremented |
| @@ -4051,7 +4002,7 @@ calling @code{(person-first-name @var{p})}, @code{(person-age | |||
| 4051 | slots by using @code{setf} on any of these place forms, for example: | 4002 | slots by using @code{setf} on any of these place forms, for example: |
| 4052 | 4003 | ||
| 4053 | @example | 4004 | @example |
| 4054 | (cl-incf (person-age birthday-boy)) | 4005 | (incf (person-age birthday-boy)) |
| 4055 | @end example | 4006 | @end example |
| 4056 | 4007 | ||
| 4057 | You can create a new @code{person} by calling @code{make-person}, | 4008 | You can create a new @code{person} by calling @code{make-person}, |
| @@ -4459,29 +4410,14 @@ user to modify @var{place}. | |||
| 4459 | Many of the advanced features of this package, such as @code{cl-defun}, | 4410 | Many of the advanced features of this package, such as @code{cl-defun}, |
| 4460 | @code{cl-loop}, etc., are implemented as Lisp macros. In | 4411 | @code{cl-loop}, etc., are implemented as Lisp macros. In |
| 4461 | byte-compiled code, these complex notations will be expanded into | 4412 | byte-compiled code, these complex notations will be expanded into |
| 4462 | equivalent Lisp code which is simple and efficient. For example, | 4413 | equivalent Lisp code which is simple and efficient. Thus, there is no |
| 4463 | the form | 4414 | performance penalty for using the more readable form in your compiled |
| 4464 | 4415 | code. | |
| 4465 | @example | ||
| 4466 | (cl-incf i n) | ||
| 4467 | @end example | ||
| 4468 | |||
| 4469 | @noindent | ||
| 4470 | is expanded at compile-time to the Lisp form | ||
| 4471 | |||
| 4472 | @example | ||
| 4473 | (setq i (+ i n)) | ||
| 4474 | @end example | ||
| 4475 | |||
| 4476 | @noindent | ||
| 4477 | which is the most efficient way of doing this operation | ||
| 4478 | in Lisp. Thus, there is no performance penalty for using the more | ||
| 4479 | readable @code{cl-incf} form in your compiled code. | ||
| 4480 | 4416 | ||
| 4481 | @emph{Interpreted} code, on the other hand, must expand these macros | 4417 | @emph{Interpreted} code, on the other hand, must expand these macros |
| 4482 | every time they are executed. For this reason it is strongly | 4418 | every time they are executed. For this reason it is strongly |
| 4483 | recommended that code making heavy use of macros be compiled. | 4419 | recommended that code making heavy use of macros be compiled. |
| 4484 | A loop using @code{cl-incf} a hundred times will execute considerably | 4420 | A loop using @code{cl-first} a hundred times will execute considerably |
| 4485 | faster if compiled, and will also garbage-collect less because the | 4421 | faster if compiled, and will also garbage-collect less because the |
| 4486 | macro expansion will not have to be generated, used, and thrown away a | 4422 | macro expansion will not have to be generated, used, and thrown away a |
| 4487 | hundred times. | 4423 | hundred times. |
| @@ -4907,7 +4843,7 @@ call to @code{make-adder} itself. | |||
| 4907 | @example | 4843 | @example |
| 4908 | (defun make-counter () | 4844 | (defun make-counter () |
| 4909 | (lexical-let ((n 0)) | 4845 | (lexical-let ((n 0)) |
| 4910 | (cl-function (lambda (&optional (m 1)) (cl-incf n m))))) | 4846 | (cl-function (lambda (&optional (m 1)) (incf n m))))) |
| 4911 | (setq count-1 (make-counter)) | 4847 | (setq count-1 (make-counter)) |
| 4912 | (funcall count-1 3) | 4848 | (funcall count-1 3) |
| 4913 | @result{} 3 | 4849 | @result{} 3 |
| @@ -5052,7 +4988,7 @@ In Emacs, these are obsolete, replaced by various features of | |||
| 5052 | 4988 | ||
| 5053 | @defmac define-modify-macro name arglist function [doc-string] | 4989 | @defmac define-modify-macro name arglist function [doc-string] |
| 5054 | This macro defines a ``read-modify-write'' macro similar to | 4990 | This macro defines a ``read-modify-write'' macro similar to |
| 5055 | @code{cl-incf} and @code{cl-decf}. You can replace this macro | 4991 | @code{incf} and @code{decf}. You can replace this macro |
| 5056 | with @code{gv-letplace}. | 4992 | with @code{gv-letplace}. |
| 5057 | 4993 | ||
| 5058 | The macro @var{name} is defined to take a @var{place} argument | 4994 | The macro @var{name} is defined to take a @var{place} argument |
| @@ -5180,8 +5116,8 @@ For example, the simple form of @code{defsetf} is shorthand for | |||
| 5180 | 5116 | ||
| 5181 | The Lisp form that is returned can access the arguments from | 5117 | The Lisp form that is returned can access the arguments from |
| 5182 | @var{arglist} and @var{store-var} in an unrestricted fashion; | 5118 | @var{arglist} and @var{store-var} in an unrestricted fashion; |
| 5183 | macros like @code{cl-incf} that invoke this | 5119 | macros that invoke this |
| 5184 | setf-method will insert temporary variables as needed to make | 5120 | setf-method should insert temporary variables as needed to make |
| 5185 | sure the apparent order of evaluation is preserved. | 5121 | sure the apparent order of evaluation is preserved. |
| 5186 | 5122 | ||
| 5187 | Another standard example: | 5123 | Another standard example: |
| @@ -5245,11 +5181,7 @@ temporary variables. In the setf-methods generated by | |||
| 5245 | @code{defsetf}, the second return value is simply the list of | 5181 | @code{defsetf}, the second return value is simply the list of |
| 5246 | arguments in the place form, and the first return value is a | 5182 | arguments in the place form, and the first return value is a |
| 5247 | list of a corresponding number of temporary variables generated | 5183 | list of a corresponding number of temporary variables generated |
| 5248 | @c FIXME I don't think this is true anymore. | 5184 | by @code{cl-gensym}. |
| 5249 | by @code{cl-gensym}. Macros like @code{cl-incf} that | ||
| 5250 | use this setf-method will optimize away most temporaries that | ||
| 5251 | turn out to be unnecessary, so there is little reason for the | ||
| 5252 | setf-method itself to optimize. | ||
| 5253 | @end defmac | 5185 | @end defmac |
| 5254 | 5186 | ||
| 5255 | @node GNU Free Documentation License | 5187 | @node GNU Free Documentation License |
| @@ -491,12 +491,18 @@ Emacs 25.1), and gnudoit (obsolete since Emacs 25.1). | |||
| 491 | ** CL-Lib | 491 | ** CL-Lib |
| 492 | 492 | ||
| 493 | +++ | 493 | +++ |
| 494 | *** Some cl-lib functions are now built-in. | 494 | *** Some cl-lib functions and macros are now built-in. |
| 495 | The functions 'cl-plusp', 'cl-minusp', 'cl-oddp', and 'cl-evenp', have | 495 | These functions or macros have been added to Emacs Lisp, and the old |
| 496 | been added to Emacs Lisp, and are thus now aliases for the built-in | 496 | names are now aliases for the built-in equivalents: |
| 497 | functions 'plusp', 'minusp', 'oddp' and 'evenp'. The old names are | 497 | - 'cl-incf' renamed to 'incf' |
| 498 | considered deprecated, and will be marked as obsolete in some future | 498 | - 'cl-decf' renamed to 'decf' |
| 499 | release. | 499 | - 'cl-oddp' renamed to 'oddp' |
| 500 | - 'cl-evenp' renamed to 'evenp' | ||
| 501 | - 'cl-plusp' renamed to 'plusp' | ||
| 502 | - 'cl-minusp' renamed to 'minusp' | ||
| 503 | |||
| 504 | The old names are considered deprecated, and will be marked as obsolete | ||
| 505 | in some future release. | ||
| 500 | 506 | ||
| 501 | +++ | 507 | +++ |
| 502 | *** 'cl-labels' now also accepts '(FUNC EXP)' bindings, like 'cl-flet'. | 508 | *** 'cl-labels' now also accepts '(FUNC EXP)' bindings, like 'cl-flet'. |
| @@ -1357,6 +1363,11 @@ change it globally with: | |||
| 1357 | (set-default-toplevel-value 'lexical-binding t) | 1363 | (set-default-toplevel-value 'lexical-binding t) |
| 1358 | 1364 | ||
| 1359 | +++ | 1365 | +++ |
| 1366 | *** New functions 'incf' and 'decf'. | ||
| 1367 | They increment or decrement the value stored in a variable (a symbol), | ||
| 1368 | or in a generalized variable. | ||
| 1369 | |||
| 1370 | +++ | ||
| 1360 | ** New functions 'plusp' and 'minusp'. | 1371 | ** New functions 'plusp' and 'minusp'. |
| 1361 | They return non-nil if a number is positive or negative, respectively, | 1372 | They return non-nil if a number is positive or negative, respectively, |
| 1362 | and signal an error if they are given a non-number. | 1373 | and signal an error if they are given a non-number. |
diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el index 2a952b57646..42460fc2c9f 100644 --- a/lisp/emacs-lisp/cl-lib.el +++ b/lisp/emacs-lisp/cl-lib.el | |||
| @@ -105,29 +105,27 @@ a future Emacs interpreter will be able to use it.") | |||
| 105 | ;; can safely be used in init files. | 105 | ;; can safely be used in init files. |
| 106 | 106 | ||
| 107 | ;;;###autoload | 107 | ;;;###autoload |
| 108 | (defmacro cl-incf (place &optional x) | 108 | (defalias 'cl-incf #'incf |
| 109 | "Increment PLACE by X (1 by default). | 109 | "Increment PLACE by X (1 by default). |
| 110 | PLACE may be a symbol, or any generalized variable allowed by `setf'. | 110 | PLACE may be a symbol, or any generalized variable allowed by `setf'. |
| 111 | The return value is the incremented value of PLACE. | 111 | The return value is the incremented value of PLACE. |
| 112 | 112 | ||
| 113 | If X is specified, it should be an expression that should | 113 | If X is specified, it should be an expression that should |
| 114 | evaluate to a number." | 114 | evaluate to a number. |
| 115 | (declare (debug (place &optional form))) | 115 | |
| 116 | (if (symbolp place) | 116 | This macro is considered deprecated in favor of the built-in macro |
| 117 | (list 'setq place (if x (list '+ place x) (list '1+ place))) | 117 | `incf' that was added in Emacs 31.1.") |
| 118 | (list 'cl-callf '+ place (or x 1)))) | ||
| 119 | 118 | ||
| 120 | (defmacro cl-decf (place &optional x) | 119 | (defalias 'cl-decf #'decf |
| 121 | "Decrement PLACE by X (1 by default). | 120 | "Decrement PLACE by X (1 by default). |
| 122 | PLACE may be a symbol, or any generalized variable allowed by `setf'. | 121 | PLACE may be a symbol, or any generalized variable allowed by `setf'. |
| 123 | The return value is the decremented value of PLACE. | 122 | The return value is the decremented value of PLACE. |
| 124 | 123 | ||
| 125 | If X is specified, it should be an expression that should | 124 | If X is specified, it should be an expression that should |
| 126 | evaluate to a number." | 125 | evaluate to a number. |
| 127 | (declare (debug cl-incf)) | 126 | |
| 128 | (if (symbolp place) | 127 | This macro is considered deprecated in favor of the built-in macro |
| 129 | (list 'setq place (if x (list '- place x) (list '1- place))) | 128 | `decf' that was added in Emacs 31.1.") |
| 130 | (list 'cl-callf '- place (or x 1)))) | ||
| 131 | 129 | ||
| 132 | (defmacro cl-pushnew (x place &rest keys) | 130 | (defmacro cl-pushnew (x place &rest keys) |
| 133 | "Add X to the list stored in PLACE unless X is already in the list. | 131 | "Add X to the list stored in PLACE unless X is already in the list. |
diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el index dcbdf6942f7..d9ba786aa7d 100644 --- a/lisp/emacs-lisp/gv.el +++ b/lisp/emacs-lisp/gv.el | |||
| @@ -315,17 +315,29 @@ The return value is the last VAL in the list. | |||
| 315 | ;; `(if (member ,v ,getter) nil | 315 | ;; `(if (member ,v ,getter) nil |
| 316 | ;; ,(funcall setter `(cons ,v ,getter)))))) | 316 | ;; ,(funcall setter `(cons ,v ,getter)))))) |
| 317 | 317 | ||
| 318 | ;; (defmacro gv-inc! (place &optional val) | 318 | ;;;###autoload |
| 319 | ;; "Increment PLACE by VAL (default to 1)." | 319 | (defmacro incf (place &optional delta) |
| 320 | ;; (declare (debug (gv-place &optional form))) | 320 | "Increment PLACE by DELTA (default to 1). |
| 321 | ;; (gv-letplace (getter setter) place | ||
| 322 | ;; (funcall setter `(+ ,getter ,(or val 1))))) | ||
| 323 | 321 | ||
| 324 | ;; (defmacro gv-dec! (place &optional val) | 322 | The DELTA is first added to PLACE, and then stored in PLACE. |
| 325 | ;; "Decrement PLACE by VAL (default to 1)." | 323 | Return the incremented value of PLACE. |
| 326 | ;; (declare (debug (gv-place &optional form))) | 324 | |
| 327 | ;; (gv-letplace (getter setter) place | 325 | See also `decf'." |
| 328 | ;; (funcall setter `(- ,getter ,(or val 1))))) | 326 | (declare (debug (gv-place &optional form))) |
| 327 | (gv-letplace (getter setter) place | ||
| 328 | (funcall setter `(+ ,getter ,(or delta 1))))) | ||
| 329 | |||
| 330 | ;;;###autoload | ||
| 331 | (defmacro decf (place &optional delta) | ||
| 332 | "Decrement PLACE by DELTA (default to 1). | ||
| 333 | |||
| 334 | The DELTA is first subtracted from PLACE, and then stored in PLACE. | ||
| 335 | Return the decremented value of PLACE. | ||
| 336 | |||
| 337 | See also `incf'." | ||
| 338 | (declare (debug (gv-place &optional form))) | ||
| 339 | (gv-letplace (getter setter) place | ||
| 340 | (funcall setter `(- ,getter ,(or delta 1))))) | ||
| 329 | 341 | ||
| 330 | ;; For Edebug, the idea is to let Edebug instrument gv-places just like it does | 342 | ;; For Edebug, the idea is to let Edebug instrument gv-places just like it does |
| 331 | ;; for normal expressions, and then give it a gv-expander to DTRT. | 343 | ;; for normal expressions, and then give it a gv-expander to DTRT. |
diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index 23b9b582a9a..77a4ec4f21c 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el | |||
| @@ -1375,9 +1375,17 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'), | |||
| 1375 | :eval (mod 10 6) | 1375 | :eval (mod 10 6) |
| 1376 | :eval (mod 10.5 6)) | 1376 | :eval (mod 10.5 6)) |
| 1377 | (1+ | 1377 | (1+ |
| 1378 | :eval (1+ 2)) | 1378 | :eval (1+ 2) |
| 1379 | :eval (let ((x 2)) (1+ x) x)) | ||
| 1379 | (1- | 1380 | (1- |
| 1380 | :eval (1- 4)) | 1381 | :eval (1- 4) |
| 1382 | :eval (let ((x 4)) (1- x) x)) | ||
| 1383 | (incf | ||
| 1384 | :eval (let ((x 2)) (incf x) x) | ||
| 1385 | :eval (let ((x 2)) (incf x 2) x)) | ||
| 1386 | (decf | ||
| 1387 | :eval (let ((x 4)) (decf x) x) | ||
| 1388 | :eval (let ((x 4)) (decf x 2)) x) | ||
| 1381 | "Predicates" | 1389 | "Predicates" |
| 1382 | (= | 1390 | (= |
| 1383 | :args (number &rest numbers) | 1391 | :args (number &rest numbers) |
diff --git a/lisp/obsolete/cl.el b/lisp/obsolete/cl.el index 5baa155c592..5fbfbb7899e 100644 --- a/lisp/obsolete/cl.el +++ b/lisp/obsolete/cl.el | |||
| @@ -282,8 +282,6 @@ | |||
| 282 | values-list | 282 | values-list |
| 283 | values | 283 | values |
| 284 | pushnew | 284 | pushnew |
| 285 | decf | ||
| 286 | incf | ||
| 287 | )) | 285 | )) |
| 288 | (let ((new (if (consp fun) (prog1 (cdr fun) (setq fun (car fun))) | 286 | (let ((new (if (consp fun) (prog1 (cdr fun) (setq fun (car fun))) |
| 289 | (intern (format "cl-%s" fun))))) | 287 | (intern (format "cl-%s" fun))))) |
diff --git a/test/lisp/emacs-lisp/cl-lib-tests.el b/test/lisp/emacs-lisp/cl-lib-tests.el index 376566958a0..d7c38b73432 100644 --- a/test/lisp/emacs-lisp/cl-lib-tests.el +++ b/test/lisp/emacs-lisp/cl-lib-tests.el | |||
| @@ -63,42 +63,6 @@ | |||
| 63 | (should (equal (cl-multiple-value-list nil) nil)) | 63 | (should (equal (cl-multiple-value-list nil) nil)) |
| 64 | (should (equal (cl-multiple-value-list (list 1 2 3)) '(1 2 3)))) | 64 | (should (equal (cl-multiple-value-list (list 1 2 3)) '(1 2 3)))) |
| 65 | 65 | ||
| 66 | (defvar cl-lib-test--special 0) | ||
| 67 | |||
| 68 | (ert-deftest cl-lib-test-incf () | ||
| 69 | (setq cl-lib-test--special 0) | ||
| 70 | (should (= (cl-incf cl-lib-test--special) 1)) | ||
| 71 | (should (= cl-lib-test--special 1)) | ||
| 72 | (should (= (cl-incf cl-lib-test--special 9) 10)) | ||
| 73 | (should (= cl-lib-test--special 10)) | ||
| 74 | (let ((var 0)) | ||
| 75 | (should (= (cl-incf var) 1)) | ||
| 76 | (should (= var 1)) | ||
| 77 | (should (= (cl-incf var 9) 10)) | ||
| 78 | (should (= var 10))) | ||
| 79 | (let ((alist)) | ||
| 80 | (should (= (cl-incf (alist-get 'a alist 0)) 1)) | ||
| 81 | (should (= (alist-get 'a alist 0) 1)) | ||
| 82 | (should (= (cl-incf (alist-get 'a alist 0) 9) 10)) | ||
| 83 | (should (= (alist-get 'a alist 0) 10)))) | ||
| 84 | |||
| 85 | (ert-deftest cl-lib-test-decf () | ||
| 86 | (setq cl-lib-test--special 0) | ||
| 87 | (should (= (cl-decf cl-lib-test--special) -1)) | ||
| 88 | (should (= cl-lib-test--special -1)) | ||
| 89 | (should (= (cl-decf cl-lib-test--special 9) -10)) | ||
| 90 | (should (= cl-lib-test--special -10)) | ||
| 91 | (let ((var 1)) | ||
| 92 | (should (= (cl-decf var) 0)) | ||
| 93 | (should (= var 0)) | ||
| 94 | (should (= (cl-decf var 10) -10)) | ||
| 95 | (should (= var -10))) | ||
| 96 | (let ((alist)) | ||
| 97 | (should (= (cl-decf (alist-get 'a alist 0)) -1)) | ||
| 98 | (should (= (alist-get 'a alist 0) -1)) | ||
| 99 | (should (= (cl-decf (alist-get 'a alist 0) 9) -10)) | ||
| 100 | (should (= (alist-get 'a alist 0) -10)))) | ||
| 101 | |||
| 102 | (ert-deftest cl-digit-char-p () | 66 | (ert-deftest cl-digit-char-p () |
| 103 | (should (eql 3 (cl-digit-char-p ?3))) | 67 | (should (eql 3 (cl-digit-char-p ?3))) |
| 104 | (should (eql 10 (cl-digit-char-p ?a 11))) | 68 | (should (eql 10 (cl-digit-char-p ?a 11))) |
diff --git a/test/lisp/emacs-lisp/gv-tests.el b/test/lisp/emacs-lisp/gv-tests.el index 5ea386e0b5d..892af4bfab1 100644 --- a/test/lisp/emacs-lisp/gv-tests.el +++ b/test/lisp/emacs-lisp/gv-tests.el | |||
| @@ -163,6 +163,42 @@ its getter (Bug#41853)." | |||
| 163 | (eval-buffer)))) | 163 | (eval-buffer)))) |
| 164 | (should (equal (get 'gv-setter-edebug 'gv-setter-edebug-prop) '(123)))) | 164 | (should (equal (get 'gv-setter-edebug 'gv-setter-edebug-prop) '(123)))) |
| 165 | 165 | ||
| 166 | (defvar gv-test--special 0) | ||
| 167 | |||
| 168 | (ert-deftest gv-incf () | ||
| 169 | (setq gv-test--special 0) | ||
| 170 | (should (= (incf gv-test--special) 1)) | ||
| 171 | (should (= gv-test--special 1)) | ||
| 172 | (should (= (incf gv-test--special 9) 10)) | ||
| 173 | (should (= gv-test--special 10)) | ||
| 174 | (let ((var 0)) | ||
| 175 | (should (= (incf var) 1)) | ||
| 176 | (should (= var 1)) | ||
| 177 | (should (= (incf var 9) 10)) | ||
| 178 | (should (= var 10))) | ||
| 179 | (let ((alist)) | ||
| 180 | (should (= (incf (alist-get 'a alist 0)) 1)) | ||
| 181 | (should (= (alist-get 'a alist 0) 1)) | ||
| 182 | (should (= (incf (alist-get 'a alist 0) 9) 10)) | ||
| 183 | (should (= (alist-get 'a alist 0) 10)))) | ||
| 184 | |||
| 185 | (ert-deftest gv-decf () | ||
| 186 | (setq gv-test--special 0) | ||
| 187 | (should (= (decf gv-test--special) -1)) | ||
| 188 | (should (= gv-test--special -1)) | ||
| 189 | (should (= (decf gv-test--special 9) -10)) | ||
| 190 | (should (= gv-test--special -10)) | ||
| 191 | (let ((var 1)) | ||
| 192 | (should (= (decf var) 0)) | ||
| 193 | (should (= var 0)) | ||
| 194 | (should (= (decf var 10) -10)) | ||
| 195 | (should (= var -10))) | ||
| 196 | (let ((alist)) | ||
| 197 | (should (= (decf (alist-get 'a alist 0)) -1)) | ||
| 198 | (should (= (alist-get 'a alist 0) -1)) | ||
| 199 | (should (= (decf (alist-get 'a alist 0) 9) -10)) | ||
| 200 | (should (= (alist-get 'a alist 0) -10)))) | ||
| 201 | |||
| 166 | (ert-deftest gv-plist-get () | 202 | (ert-deftest gv-plist-get () |
| 167 | ;; Simple `setf' usage for `plist-get'. | 203 | ;; Simple `setf' usage for `plist-get'. |
| 168 | (let ((target (list :a "a" :b "b" :c "c"))) | 204 | (let ((target (list :a "a" :b "b" :c "c"))) |