如何理解“格林斯潘第十定律”?

任何足够复杂的C语言或者Fortran程序中,都包含一个临时特设的、不合规范的、充满程序错误的、运行速度很慢的、只有一半功能的Common Lisp实现。

这一理论应当被视为确实有实例印证的实践性结论,还是应该视作 Lisp 社区一小部分狂热分子的口嗨?

过时的玩意。现在的话,当个笑话看就行了,过去不是太清楚。

2 个赞

真实例子,gnucap 为了解释器能从动态库加载命令,实现了一个经常内存泄漏的弱化不标准 Common Lisp

Fortran 的话,一堆人有实现类似 sympy 功能的需求,结果就是比如 GitHub - jacobwilliams/fortran_function_parser: Modern Fortran function parser. An update of "fparser" by Roland Schmehl

实际上可以理解为,实践当中编程语言的动态特性是不可缺的,再怎么嘴硬说这样的功能不需要,最后还是会发现是在重新发明这些 Common Lisp 标配的特性

5 个赞

是说程序的配置文件吧, 开始的时候规则都很简单, 复杂到一定程度后就会变成一门编程语言专门来写配置(或者写不下去,需要专门开发一个工具用于配置文件生成). 而lisp做其它可能不太行, 但作为程序的配置文件语言还是很合适的

4 个赞

对。程序稍微复杂一点强大一点儿之后,绝大多数都需要一个配置变化选项之类的交互途径。然后就需要解析这个交互的媒介。如果不强调lisp,那么然后就需要一个解释器/编译器。不过lisp是最合适干这个的。

2 个赞

有意思,不过我没有记错的话,GNU 是有自己实现了 Scheme 和 CLisp 的,为什么不直接嵌入那个实现呢?

因为要兼容的是 SPICE 的语法,要 lisp 又没用,GNU 项目又不是全都是同一批作者,边缘项目包括 gnucap,GNU Common Lisp, GNU CLISP 都相当于只有挂名 GNU,项目也不会从 GNU 收到资助,有需要比如 GnuPG 也都靠是自己去拉,开发者只有一人到数人,和其它项目的开发没什么联系才是正常现象,也没有一定要支持其它项目的义务,核心的 GCC, Emacs, Guile,也只是项目关注度更高有更多人在合作开发,作者在意自己保有软件版权的话哪怕都是 GPL 也不会随便用其它项目的代码。

3 个赞

这个问题的核心可能是 “动态性”。编译型语言在设计的时候,对改变(扩展)binary 程序的行为的支持,很多时候是不足的。有很多例子,比如 pandoc 内置了一个 lua 解释器等等

不过也有一些例外,JVM 可以动态加载新的类。只要定义好接口,插件可以通过配置文件传进去。这种方式已经满足了很多需求,所以 Java 系的项目大部分不需要内置别的动态语言解释器。

5 个赞

从他说这话到现在软件行业的发展和实践来看,大多数人是不信的,不然现在应该大家都会 lisp,lisp 的教程也该到处都是,但现实却是很多只有一半或者更少功能的 common lisp 活在各种项目中,而 lisp 依然只是少数人心中的白月光。

有没有一种可能就是,现实中真的只需要少量的 lisp 功能就够了而不需要一个完整的 lisp 解释器?

2 个赞

90% 的 C 程序用不到 atan2 函数,但是 C 标准库带了。

用不上是正常的,但你用不上不代表完全没有用

你这例子很不好,编程语言在其 math 的相关库中提供尽量多的数学函数是符合其通用语言的设计需求和目标的,而如果需求只是实现不同程度的动态配置,一个完整的解释器是几个项目真正需要的?

对开发者来说,有些项目自己实现一个简单配置语言比起维护一个完整的 lisp 解释器还是要简单很多。当然,不否认有些项目开始是这样想的,但后来这个配置语言不断膨胀可能就变成一个什么都比不上 lisp, 同时更难维护的东西,但这形成原因也不是开始的设计错误,而是在项目发展中没有发现需求的变化,即时调整设计思路而累积出来的(当发现配置文件需要逻辑判断的时候是否就该考虑是否应该引入一个经过验证的正经脚步语言?)。解决方案也不该是项目一开始就来个 lisp 搞配置,而是要么仔细考虑始终保持一个功能单一的自己设计的配置语言,或者在某一阶段将其抛弃转为使用一个通用的脚本语言。

而对于一开始就有明确需求需要一个解释器的项目来说,在现在这个时间点,我个人认为 common lisp 也不是一个好的选择,lisp 过于灵活,上手成本,维护成本都比 lua 要高,而会的人也比会 lua 的人少。

提供数学函数的根本原因是如果不提供,大部分人做的 naive 实现是有问题的,没这个功底能做的和标准库差不多好

同理,如果一个解释器的功能大部分人实现都是有问题的,那当然是有现成的最好

1 个赞

我认为你这个说法在大部分前 Win10 时代是没问题的,Win10 开始,Windows 开始菜单、设置也是 .NET 写的了。.NET 本身岂非一个复杂的 C 程序里只有一半功能的 Common Lisp?以其动态性,最大的区别就是非 S-expr 了,C# 也有编译时执行程序呀。当然 common lisp 很多地方做的不如 .NET 好,尤其是以今天的眼光来看,没有足够大的标准库。当然最大的缺陷,实话实说,不能否认的是没有一个像 microsoft 这样花重金支持的公司,不然什么语言不也能捧起来?比如君所言 lua 我看潜力非必局限于游戏产业和配置。

1 个赞

对这个定律不了解,于是去查维基百科,发现还是不理解。

不过发现这个词条下推荐了另一个叫作 * Zawinski’s law of software envelopment 的定律,倒是非常契合本论坛主题😄:

Zawinski’s Law of Software Envelopment, also known as Zawinski’s Law, states:

Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can.

Some have interpreted this as commenting on the phenomenon of software bloating with popular features:[31][32]

Zawinski himself has stated:[33]

My point was not about copycats, it was about platformization. Apps that you “live in” all day have pressure to become everything and do everything. An app for editing text becomes an IDE, then an OS. An app for displaying hypertext documents becomes a mail reader, then an OS.

最后这段翻译是:

我想说的不是山寨,而是平台化。你整天 "生活 "在其中的应用程序面临着变成一切、做一切的压力。一个编辑文本的应用程序会变成一个集成开发环境,然后变成一个操作系统。一个用于显示超文本文档的应用程序变成了邮件阅读器,然后又变成了操作系统。

2 个赞

我倒是第一次知道 Zawinsk 说过这个,我想他这里在讨论的是 emacs。

私以为他说的很对,但他讨论的不能覆盖格林斯潘第十定律,因为即使是应用程序整体上也是固定的。以微信举例,尽管有小程序但依然以微信聊天、钱包等为主体。

而格林斯潘第十定律提及了另一方面,随着 C/Fortran 等语言写的代码变得复杂,随着 Java 写的代码变得复杂,这里要加上 Java 因为微信是 Java 实现的,即使加入了 lua 作为拓展语言,即使有小程序作为外挂模块,也因此加入了 javascript,那它 Java 语言部分实现的代码除非更新应用,也不能改变,也不能抛弃。这里必须理解 Android 只允许通过安装更新 Java,但允许随时更新数据,lua 和 js 代码属于数据。更别说应用中的 C 代码热更新都算黑魔法,更不能改变。所以 js 和 lua 便成了微信 C/Java 代码的外挂。

格林斯潘第十定律提及 common lisp,那就不能不忽视 common lisp 即使在运行过程中也能执行新的代码,定义或更新的函数,编译函数,编译好的代码也不用去文件中加载,就在内存中,而编译出来的代码理论上又有 C++ 的速度。当然要承认 common lisp 没有一个合格的编译器能真的达到 g++/clang++ -O3 级别优化后编译出代码的执行速度,但常见编译器如 sbcl 编译代码的速度又是 clang 都不能企及的。最后也要说明 js/lua 代码的拓展性,二者不能拓展语法,其拓展性也不如 commom lisp。

当然也要谈论谈论格林斯潘第十定律的问题,这定律从当时看还是现在看都不负责任。在 1990 年 ~ 2000 年,common lisp 作为一门编程语言,占用的内存太多了,100 mb ~ 500 mb 的内存使用,当时很少有个人电脑能无压力运行 common lisp 环境。2000 年 ~ 今天,也再没有大型社区有使用 common lisp 编程的热情,当初那些设计这门语言的人都已经退休了,以至于这门当时过大的语言在今天看起来居然有点小?

综上格林斯潘第十定律或许没错但如今也没几人愿意用 common lisp 开发了。理论上 common lisp 有使用一种语言就拥有接近 C++ 的速度,同时拥有超过 lua/js 的可变性,其一人便可承担 c + lua 的主语言 + 外挂模式。但另一方面说,common lisp 发展落后类库不足,尽管确有商用但客户稀少哉。

以上是个人观点。

2 个赞