LWN:在Emacs中使用Common Lisp!

关注了就能看到更多这么棒的文章哦~

Using Common Lisp in Emacs

By Jake Edge
November 14, 2023
ChatGPT translation
https://lwn.net/Articles/951090/

Lisp 是仍在使用的最古老的编程语言之一,但在其超过 60 年的历史中已经演变成多个变种。其中两个较为突出的后代分别是 Common Lisp和Emacs Lisp(或 Elisp),它们在某种程度上有一定的关联,但也存在一些分歧。最近在 emacs-devel 邮件列表中的一些讨论显示,一些来自 Common Lisp 的特征在 Elisp 中并不完全受欢迎,至少在由 Emacs 项目本身维护的代码中是如此。

讨论可以至少追溯到 9 月中旬,当时关键字参数(keyword arguments)的主题讨论在另一个上下文中被提到,而关键字参数在 Common Lisp 中被广泛使用,当时 Richard Stallman 指出,尽管 Elisp 中有一定程度的 Common Lisp 兼容性,但“不应该经常使用”。 Alfred M. Szmidt 同意,指出 Common Lisp 的有用部分可以被采纳,但:“没有必要为了与 Common Lisp 兼容性而使 Emacs Lisp 变得复杂。” 与此同时,Emacs 维护者 Eli Zaretskii 对这里提供了一些数据来量化了:“Emacs 中的 1637 个 Lisp 文件中有 466 个需要 cl-lib(其中一些仅在编译时需要,也就是说它们仅使用宏)。” Elisp 的"cl-lib"库(以前是"cl",但是已经被标记为废弃了,因为我的 Emacs 经常提醒我这一点)为那些需要或希望在 Emacs 中使用 cl 的人提供了各种兼容性宏和函数。

这个讨论在一个月内基本上停滞了,但 Stallman 在 10 月中旬重新提出这个问题;他试图澄清 Emacs 中对 cl-lib 使用的问题。在他看来,仅在编译时使用 cl-lib 的宏并不是什么大问题,但在运行时使用 cl-lib 可能是更严重的情况。正如他在 2003年所说的,Stallman 不喜欢 Common Lisp;他对 Common Lisp 的许多决策“评价不高”,尤其是关键字参数。

Zaretskii 报告说,有 226 个地方在运行时使用 cl-lib,Emanuel Berg 转换为百分比,也就是 28%的 Elisp 文件使用 cl-lib,15%在编译时,14%在运行时。 Stallman 表示,他最关心的是那些可能导致在没有进行过定制时(例如使用 -Q 命令行选项)启动 Emacs 时加载了 cl-lib 的情况。

Alan Mackenzie 试图追踪 每个 Elisp 文件中 cl- 符号的使用次数,他认为移除所有这些符号将是一项巨大的工作:“因为有很多贡献者认为 cl-lib 只是 Emacs 的一个普通部分,可以自由使用,无需约束”,尽管他自己不属于这些贡献者之一。 Zaretskii 质疑了这个数字,但表示 cl-lib 的一些用途可能是不可避免的:

我们不能指望人们不使用他们习惯的宏来贡献代码。只要最终能不加载 cl-lib,我认为就足够了。

Berg 纳闷 人们为什么关注在某些情况下不加载 cl-lib;“我认为很明显 cl-lib 被广泛使用,可能是因为人们发现它很有用。” Zaretskii 回答说,这很重要,因为该项目决定在“vanilla Emacs”中不加载 cl-lib,因为这样做会导致“膨胀(bloat)、不必要的命名空间污染等问题”。虽然对于“emacs -Q”来说不会加载 cl-lib,但是 Berg 指出在 Emacs 启动后不久它可能会加载,因为调试器、本地编译的包,以及许多其他 Emacs 包都依赖于 cl-lib。Zaretskii 对此不感兴趣:

对我们来说重要的是,在“emacs -Q”中不加载这些不必要的东西,也就不被倾倒(dump)和预加载(preload)到未经过用户定制的 Emacs 会话中。这使得用户可以从最简洁的 Emacs 开始,然后加载他们需要的内容,而不会因为加载许多从不需要或想要的东西而受到“惩罚”。

Emacs 预加载不必要的东西是不干净的做法,我们试图避免这种不干净。

有人提出,如今,cl-lib 只是 Emacs 环境中预期的一部分,因此也许应该考虑预加载它。可以猜到,这并没有取得很多赞同。事实上,当前的长篇讨论是另一个讨论建议将 Emacs 切换到使用 Common Lisp 以减少编辑器的 C 代码占用的一个分支。毫不奇怪,这个建议更为不受欢迎。

主要反对意见是开发人员必须学习 Common Lisp 的函数等,以便理解使用它们的代码。虽然 Zaretskii 认为开发人员在自己的代码或 Emacs 扩展中使用 cl-lib 没有问题,但他不希望在启动 Emacs 时看到它用在预加载的 vanilla Elisp 代码中。一些人认为这是一种意识形态的举动,但 Zaretskii 表示这只是 Emacs 维护者做出的一种可维护性选择。

然而,Stallman 走得更远;他认为调试器和本地编译扩展使用 cl-lib 都是不应该的:

我们应该修复调试器和本地编译,确保不加载 cl-lib。

如果加载一个专门的包,而它使用了 cl-lib,这并不太糟糕。但调试器可以加载来调试任何东西,甚至是与你无关的程序。调试器加载 cl-lib 是不礼貌的。

同样,对于本地编译,毕竟你可能需要重新编译任何东西。

然而,Zaretskii 并不认为这些用法有问题(例如:“调试器出于合理原因使用了 cl-lib。”)。他表示他不认为有必要“在这方面浪费我们的资源”。Stefan Kangas 赞同:“让我们把精力集中在解决真正的问题上”。

Stallman 对Mackenzie的清单进行了一些调查,发现 byte-run.el 是一个误报,但abbrev minor mode使用了在 cl-lib 中定义的cl-pushnew 宏。“作为一个通用的 minor 模式,像 abbrev.el 这种,不应该加载 cl-lib。”他建议将 cl-pushnew 的定义移动到其他地方,以防止加载该库。然后应该调查和修复清单上的其他条目。之后:

一旦我们修复了它们,我们可以加入一个回归测试,以验证任何人随时可能加载的各种包是否不使用 cl-lib。有了这个,类似这样的错误将立即被捕获。

Zaretskii 指出, cl-pushnew 只是对 cl-lib 中另一个函数的很薄的封装,因此移动它不会阻止加载该库。与此同时,编写回归测试将会有些棘手,因为我们的测试套件基础设施,ert.el,本身广泛使用 cl-lib。Stallman 提出了一种新的使用 cl-pushnew 的代码的方式,但这更冗长(重复代码更多)—人们对它是否真的是一种改进存在分歧。

然而,Zaretskii 表示,现在 Emacs 维护者几乎是必须“熟悉 cl-lib 和 cl-macs 功能”的,并且这并不是什么高深的知识。Mackenzie 强烈反对这是一种轻松掌握这些知识的想法:

我简直没有足够的脑力去记住这种一团糟的、命名混乱、文档贫乏的东西。[…] 我经常花费,也许,一半的调试时间去理解一些 cl-* 到底是什么,而不是集中精力解决要调试的问题。

正是这种额外的复杂性让 Stallman 在设计 Elisp 时试图避免,Bob Rogers 说; “他认为 cl-lib.el 是一个正在改变 Emacs Lisp 的木马”。Stallman 同意这一点,并指出他的印象是 cl-lib 只是作为一个可选的扩展,这没问题,但他反对让它变得必不可少的做法,而事情正朝这个方向发展。

两者之间没有明确的分界线,也没有简单的测试来确定我们当前的情况实际上是哪一个。相反,有一个从“CL [Common Lisp]支持可用,但您可以忽略它”到“CL 构造是 Emacs Lisp 的一个基本且不可避免的部分”一直运行的谱系。

我提出的具体实际问题是评估我们现在沿着该谱系的位置的努力。当然,对于这个问题的回答也不是精确的。但我对 Emacs 在走向后者的路上走得有多远感到非常惊讶。

然而,还有其他的库也给 Elisp 增加了复杂性,所以 João Távora 好奇为什么在这方面 cl-lib 会得到特殊对待:

那么为什么这么专注于 cl-lib.el?为什么不批评 seq.el 和 map.el 和 pcase.el 的使用,它们都“添加了许多函数,其中有许多细节”?为什么这些库似乎就未受到这种讨论?

他 随后进行了一些对 cl-lib 处理方式的进一步分析;有其他添加到 Elisp 的东西一直以来都被采纳了,其中一些甚至已经到了被预加载的地步(例如为序列函数提供 seq.el 库)。这其中的一部分差异是 Stallman 真的不喜欢 Common Lisp 中关键字参数的普及,这是他不想在 Elisp 中传播的东西。一些讨论添加 Elisp pushnew 以替代 cl-pushnew 显示他并不想让 Elisp 版本支持后者的关键字参数,因此它不会是一个完全替代。有一些地方 Stallman 表示,关键字参数在 Elisp 中可能是有道理的,比如对于sort,但简单的函数和宏不应该添加它们。

避免 cl-lib 的提议要求更改 abbrev 小模式来避免使用 cl-pushnew ,并不是 Zaretskii 认为需要的,尽管如果“结果很干净,经过测试,而且不是可怕地复杂”,他也不会反对。“在其设施被充分利用时加载 cl-lib 没有问题”。Stallman 不同意,他表示“已决定开始修复一些不使用运行时 CL 功能的文件”

对于外行人来说,Emacs 中避免使用 cl-lib(以及 Common Lisp 总体)似乎有点奇怪,关于其使用的“规则”似乎相当武断—甚至是创作者和当前维护者都无法达成一致意见。显然需要在可维护性和减少 Emacs 黑客需要了解的 Lisp 构造的数量之间取得平衡,但人们不禁要思考这个平衡是否向任何一方倾斜得太远。Stallman(和其他一些人)显然认为是,但 Common Lisp 也有相当多的 Lisp 黑客—许多人使用 Emacs 作为他们的开发环境—因此这种情况对于这位(Common)Lisp 黑客来说似乎有点令人困惑。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

format,png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值