emacs lisp 中的 `let loop`(名为 let)替代方案
`let loop` (named let) alternative in emacs lisp
在 Scheme 中有一个 let loop
构造,它与就地创建自递归 lambda(又名 'named let')本质上相同。例如,6 的阶乘可以写成:
(let fact ([x 6])
(if (< 1 x)
(* x (fact (- x 1)))
x))
问题是:elisp有没有替代方案。如果存在,它是否在可能的情况下执行尾递归优化?
您正在寻找 cl-labels
。请参阅 以获取与您的代码非常相似的示例(以及其他一些相关设施)。
另见:C-hig (cl)Function Bindings
does it perform tail recursion optimization where possible?
不,Emacs Lisp 中没有 TCO,除了正在进行中的 native-compilation 功能(目前默认情况下禁用它,因此可能不被认为已准备好用于一般用途;但即使如果是的话,除了个人使用之外,依赖它是有风险的,因为假设其他人 也 是 运行 本机编译代码是不安全的).
出于这个原因,elisp 程序员通常会回避任意递归,而倾向于使用迭代技术。
Elisp 有一个 named-let
特殊形式,可以保证尾调用优化:https://www.gnu.org/software/emacs/manual/html_node/elisp/Local-Variables.html#index-named_002dlet
虽然我不知道它是什么时候添加的。
在 Scheme 中有一个 let loop
构造,它与就地创建自递归 lambda(又名 'named let')本质上相同。例如,6 的阶乘可以写成:
(let fact ([x 6])
(if (< 1 x)
(* x (fact (- x 1)))
x))
问题是:elisp有没有替代方案。如果存在,它是否在可能的情况下执行尾递归优化?
您正在寻找 cl-labels
。请参阅
另见:C-hig (cl)Function Bindings
does it perform tail recursion optimization where possible?
不,Emacs Lisp 中没有 TCO,除了正在进行中的 native-compilation 功能(目前默认情况下禁用它,因此可能不被认为已准备好用于一般用途;但即使如果是的话,除了个人使用之外,依赖它是有风险的,因为假设其他人 也 是 运行 本机编译代码是不安全的).
出于这个原因,elisp 程序员通常会回避任意递归,而倾向于使用迭代技术。
Elisp 有一个 named-let
特殊形式,可以保证尾调用优化:https://www.gnu.org/software/emacs/manual/html_node/elisp/Local-Variables.html#index-named_002dlet
虽然我不知道它是什么时候添加的。