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

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