Commit 0d363553 authored by Stefan Monnier's avatar Stefan Monnier

* lisp/emacs-lisp/subr-x.el (named-let): New macro

parent 66439d31
Pipeline #8869 failed with stages
in 32 minutes and 12 seconds
......@@ -1554,6 +1554,13 @@ buttons in it.
This function takes a string and returns a string propertized in a way
that makes it a valid button.
** subr-x
*** A number of new string manipulation functions have been added.
'string-clean-whitespace', 'string-fill', 'string-limit',
'string-lines', 'string-pad' and 'string-chop-newline'.
*** New macro `named-let` that provides Scheme's "named let" looping construct
** Miscellaneous
......@@ -1593,11 +1600,6 @@ length to a number).
*** New user option 'authinfo-hide-elements'.
This can be set to nil to inhibit hiding passwords in ".authinfo" files.
*** A number of new string manipulation functions have been added.
'string-clean-whitespace', 'string-fill', 'string-limit',
'string-lines', 'string-pad' and 'string-chop-newline'.
*** New variable 'current-minibuffer-command'.
This is like 'this-command', but it is bound recursively when entering
......@@ -389,6 +389,28 @@ it makes no sense to convert it to a string using
(set-buffer source-buffer)
(replace-buffer-contents tmp-buffer max-secs max-costs)))))))))
(defmacro named-let (name bindings &rest body)
"Looping construct taken from Scheme.
Like `let', bind variables in BINDINGS and then evaluate BODY,
but with the twist that BODY can evaluate itself recursively by
calling NAME, where the arguments passed to NAME are used
as the new values of the bound variables in the recursive invocation."
(declare (indent 2) (debug (symbolp (&rest (symbolp form)) body)))
(require 'cl-lib)
(let ((fargs (mapcar (lambda (b) (if (consp b) (car b) b)) bindings))
(aargs (mapcar (lambda (b) (if (consp b) (cadr b))) bindings)))
;; According to the Scheme semantics of named let, `name' is not in scope
;; while evaluating the expressions in `bindings', and for this reason, the
;; "initial" function call below needs to be outside of the `cl-labels'.
;; When the "self-tco" eliminates all recursive calls, the `cl-labels'
;; expands to a lambda which the byte-compiler then combines with the
;; funcall to make a `let' so we end up with a plain `while' loop and no
;; remaining `lambda' at all.
(cl-labels ((,name ,fargs . ,body)) #',name)
. ,aargs)))
(provide 'subr-x)
;;; subr-x.el ends here
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment