diff options
| author | Noam Postavsky | 2018-06-12 18:41:46 -0400 |
|---|---|---|
| committer | Noam Postavsky | 2018-06-19 20:02:16 -0400 |
| commit | e292c0973cf7a92819d312ea8a828b67e6adf1ab (patch) | |
| tree | 5ae59aef028cd644b87d6d4d8909972515a2a3b4 /lisp | |
| parent | 36737705b451ad4c765baa5789e3ceb752ee07a3 (diff) | |
| download | emacs-e292c0973cf7a92819d312ea8a828b67e6adf1ab.tar.gz emacs-e292c0973cf7a92819d312ea8a828b67e6adf1ab.zip | |
Fix #'fun handling inside `labels' (Bug#31792)
* lisp/emacs-lisp/cl.el (labels): Apply the equivalent of the
cl-labels change from 2015-01-16 "* lisp/emacs-lisp/cl-macs.el: Fix
last change".
* test/lisp/emacs-lisp/cl-tests.el (labels-function-quoting): New
test.
* lisp/emacs-lisp/cl-macs.el (cl-flet, cl-labels): Improve docstring,
link to relevant manual page.
* doc/misc/cl.texi (Function Bindings): Don't imply that function
cells of symbols are modified by cl-flet. Don't claim that cl-flet or
cl-labels affect references of the form (quote FUNC).
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/emacs-lisp/cl-macs.el | 17 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl.el | 7 |
2 files changed, 17 insertions, 7 deletions
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 9c47ceae18e..0854e665b9b 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el | |||
| @@ -1964,13 +1964,16 @@ a `let' form, except that the list of symbols can be computed at run-time." | |||
| 1964 | ;;;###autoload | 1964 | ;;;###autoload |
| 1965 | (defmacro cl-flet (bindings &rest body) | 1965 | (defmacro cl-flet (bindings &rest body) |
| 1966 | "Make local function definitions. | 1966 | "Make local function definitions. |
| 1967 | Like `cl-labels' but the definitions are not recursive. | 1967 | Each definition can take the form (FUNC EXP) where |
| 1968 | Each binding can take the form (FUNC EXP) where | ||
| 1969 | FUNC is the function name, and EXP is an expression that returns the | 1968 | FUNC is the function name, and EXP is an expression that returns the |
| 1970 | function value to which it should be bound, or it can take the more common | 1969 | function value to which it should be bound, or it can take the more common |
| 1971 | form \(FUNC ARGLIST BODY...) which is a shorthand | 1970 | form \(FUNC ARGLIST BODY...) which is a shorthand |
| 1972 | for (FUNC (lambda ARGLIST BODY)). | 1971 | for (FUNC (lambda ARGLIST BODY)). |
| 1973 | 1972 | ||
| 1973 | FUNC is defined only within FORM, not BODY, so you can't write | ||
| 1974 | recursive function definitions. Use `cl-labels' for that. See | ||
| 1975 | info node `(cl) Function Bindings' for details. | ||
| 1976 | |||
| 1974 | \(fn ((FUNC ARGLIST BODY...) ...) FORM...)" | 1977 | \(fn ((FUNC ARGLIST BODY...) ...) FORM...)" |
| 1975 | (declare (indent 1) (debug ((&rest (cl-defun)) cl-declarations body))) | 1978 | (declare (indent 1) (debug ((&rest (cl-defun)) cl-declarations body))) |
| 1976 | (let ((binds ()) (newenv macroexpand-all-environment)) | 1979 | (let ((binds ()) (newenv macroexpand-all-environment)) |
| @@ -2012,9 +2015,13 @@ Like `cl-flet' but the definitions can refer to previous ones. | |||
| 2012 | 2015 | ||
| 2013 | ;;;###autoload | 2016 | ;;;###autoload |
| 2014 | (defmacro cl-labels (bindings &rest body) | 2017 | (defmacro cl-labels (bindings &rest body) |
| 2015 | "Make temporary function bindings. | 2018 | "Make local (recursive) function definitions. |
| 2016 | The bindings can be recursive and the scoping is lexical, but capturing them | 2019 | Each definition can take the form (FUNC ARGLIST BODY...) where |
| 2017 | in closures will only work if `lexical-binding' is in use. | 2020 | FUNC is the function name, ARGLIST its arguments, and BODY the |
| 2021 | forms of the function body. FUNC is defined in any BODY, as well | ||
| 2022 | as FORM, so you can write recursive and mutually recursive | ||
| 2023 | function definitions. See info node `(cl) Function Bindings' for | ||
| 2024 | details. | ||
| 2018 | 2025 | ||
| 2019 | \(fn ((FUNC ARGLIST BODY...) ...) FORM...)" | 2026 | \(fn ((FUNC ARGLIST BODY...) ...) FORM...)" |
| 2020 | (declare (indent 1) (debug cl-flet)) | 2027 | (declare (indent 1) (debug cl-flet)) |
diff --git a/lisp/emacs-lisp/cl.el b/lisp/emacs-lisp/cl.el index d53c8e0bbcf..f6643158d2d 100644 --- a/lisp/emacs-lisp/cl.el +++ b/lisp/emacs-lisp/cl.el | |||
| @@ -466,9 +466,12 @@ rather than relying on `lexical-binding'." | |||
| 466 | (push var sets) | 466 | (push var sets) |
| 467 | (push (cons (car binding) | 467 | (push (cons (car binding) |
| 468 | `(lambda (&rest cl-labels-args) | 468 | `(lambda (&rest cl-labels-args) |
| 469 | (cl-list* 'funcall ',var | 469 | (if (eq (car cl-labels-args) cl--labels-magic) |
| 470 | cl-labels-args))) | 470 | (list cl--labels-magic ',var) |
| 471 | (cl-list* 'funcall ',var cl-labels-args)))) | ||
| 471 | newenv))) | 472 | newenv))) |
| 473 | ;; `lexical-let' adds `cl--function-convert' (which calls | ||
| 474 | ;; `cl--labels-convert') as a macroexpander for `function'. | ||
| 472 | (macroexpand-all `(lexical-let ,vars (setq ,@sets) ,@body) newenv))) | 475 | (macroexpand-all `(lexical-let ,vars (setq ,@sets) ,@body) newenv))) |
| 473 | 476 | ||
| 474 | ;; Generalized variables are provided by gv.el, but some details are | 477 | ;; Generalized variables are provided by gv.el, but some details are |