diff options
| author | Stefan Monnier | 2021-01-20 14:12:50 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2021-01-20 14:13:15 -0500 |
| commit | 0d3635536d4ed8ada6946e98e7d9f03fa443bc36 (patch) | |
| tree | e63612c169f7a83cb0217c53f9d10722a8d063cc | |
| parent | 66439d31ad2a63753d29e4582b76b36b9363d96b (diff) | |
| download | emacs-0d3635536d4ed8ada6946e98e7d9f03fa443bc36.tar.gz emacs-0d3635536d4ed8ada6946e98e7d9f03fa443bc36.zip | |
* lisp/emacs-lisp/subr-x.el (named-let): New macro
| -rw-r--r-- | etc/NEWS | 12 | ||||
| -rw-r--r-- | lisp/emacs-lisp/subr-x.el | 22 |
2 files changed, 29 insertions, 5 deletions
| @@ -1554,6 +1554,13 @@ buttons in it. | |||
| 1554 | This function takes a string and returns a string propertized in a way | 1554 | This function takes a string and returns a string propertized in a way |
| 1555 | that makes it a valid button. | 1555 | that makes it a valid button. |
| 1556 | 1556 | ||
| 1557 | ** subr-x | ||
| 1558 | +++ | ||
| 1559 | *** A number of new string manipulation functions have been added. | ||
| 1560 | 'string-clean-whitespace', 'string-fill', 'string-limit', | ||
| 1561 | 'string-lines', 'string-pad' and 'string-chop-newline'. | ||
| 1562 | |||
| 1563 | *** New macro `named-let` that provides Scheme's "named let" looping construct | ||
| 1557 | 1564 | ||
| 1558 | ** Miscellaneous | 1565 | ** Miscellaneous |
| 1559 | 1566 | ||
| @@ -1594,11 +1601,6 @@ length to a number). | |||
| 1594 | This can be set to nil to inhibit hiding passwords in ".authinfo" files. | 1601 | This can be set to nil to inhibit hiding passwords in ".authinfo" files. |
| 1595 | 1602 | ||
| 1596 | +++ | 1603 | +++ |
| 1597 | *** A number of new string manipulation functions have been added. | ||
| 1598 | 'string-clean-whitespace', 'string-fill', 'string-limit', | ||
| 1599 | 'string-lines', 'string-pad' and 'string-chop-newline'. | ||
| 1600 | |||
| 1601 | +++ | ||
| 1602 | *** New variable 'current-minibuffer-command'. | 1604 | *** New variable 'current-minibuffer-command'. |
| 1603 | This is like 'this-command', but it is bound recursively when entering | 1605 | This is like 'this-command', but it is bound recursively when entering |
| 1604 | the minibuffer. | 1606 | the minibuffer. |
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index b90227da42f..a4514454c0b 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el | |||
| @@ -389,6 +389,28 @@ it makes no sense to convert it to a string using | |||
| 389 | (set-buffer source-buffer) | 389 | (set-buffer source-buffer) |
| 390 | (replace-buffer-contents tmp-buffer max-secs max-costs))))))))) | 390 | (replace-buffer-contents tmp-buffer max-secs max-costs))))))))) |
| 391 | 391 | ||
| 392 | (defmacro named-let (name bindings &rest body) | ||
| 393 | "Looping construct taken from Scheme. | ||
| 394 | Like `let', bind variables in BINDINGS and then evaluate BODY, | ||
| 395 | but with the twist that BODY can evaluate itself recursively by | ||
| 396 | calling NAME, where the arguments passed to NAME are used | ||
| 397 | as the new values of the bound variables in the recursive invocation." | ||
| 398 | (declare (indent 2) (debug (symbolp (&rest (symbolp form)) body))) | ||
| 399 | (require 'cl-lib) | ||
| 400 | (let ((fargs (mapcar (lambda (b) (if (consp b) (car b) b)) bindings)) | ||
| 401 | (aargs (mapcar (lambda (b) (if (consp b) (cadr b))) bindings))) | ||
| 402 | ;; According to the Scheme semantics of named let, `name' is not in scope | ||
| 403 | ;; while evaluating the expressions in `bindings', and for this reason, the | ||
| 404 | ;; "initial" function call below needs to be outside of the `cl-labels'. | ||
| 405 | ;; When the "self-tco" eliminates all recursive calls, the `cl-labels' | ||
| 406 | ;; expands to a lambda which the byte-compiler then combines with the | ||
| 407 | ;; funcall to make a `let' so we end up with a plain `while' loop and no | ||
| 408 | ;; remaining `lambda' at all. | ||
| 409 | `(funcall | ||
| 410 | (cl-labels ((,name ,fargs . ,body)) #',name) | ||
| 411 | . ,aargs))) | ||
| 412 | |||
| 413 | |||
| 392 | (provide 'subr-x) | 414 | (provide 'subr-x) |
| 393 | 415 | ||
| 394 | ;;; subr-x.el ends here | 416 | ;;; subr-x.el ends here |