"let loop"(名为 let)在 Emacs Lisp 中的替代



在Scheme中有一个let loop结构,它本质上与就地创建自递归lambda(又名"命名let")相同。例如,阶乘 6 可以写为:

(let fact ([x 6])
(if (< 1 x)
(* x (fact (- x 1)))
x))

问题是:在 elisp 中还有其他选择吗?如果存在,它是否在可能的情况下执行尾递归优化?

你正在寻找cl-labels. 有关与您的代码非常相似的示例(以及其他一些相关工具),请参阅 https://stackoverflow.com/a/39564067/324105。

参见:C-hig(cl)Function Bindings

它是否在可能的情况下执行尾递归优化?

不,Emacs Lisp 中没有 TCO,除了正在进行的本机编译功能(它目前默认处于禁用状态,因此可能还没有准备好用于一般用途;但即使是这样,依赖它而不是个人使用也是有风险的,因为假设其他人也将运行本机编译的代码是不安全的)。

出于这个原因,elisp程序员通常避免任意递归,转而使用迭代技术。

Elisp 有一个named-let特殊形式,可以保证尾调用优化: https://www.gnu.org/software/emacs/manual/html_node/elisp/Local-Variables.html#index-named_002dlet

我不知道它是什么时候添加的。

最新更新