一年后,关于 Scheme,我的思考是:将 Scheme 作为应用的嵌入式语言,给应用插件和扩展功能。定位类似于 Lua。 自从诞生开始 Scheme 就将极简主义刻到了骨子里。R5RS 规范篇幅只有短短 50 页,成为大家津津乐道的话题。R6RS 大量扩充篇幅,反倒引起争议。R7RS 干脆推翻重来,稳定是基于 R5RS 的升级,抛弃了 R6RS。 「简单 + 强大」是 Scheme 的最大特色;生态弱开源库少是它的短板。 作为应用的嵌入式语言,生态弱开源库少压根不成问题。没有 HTTP 库,没有 JSON 库,不支持 ProtoBuf/gRPC,甚至不支持 TCP ,不支持本地文件 IO,全都不是问题。只要应用将自己的能力暴露出来,Scheme 就可以打好配合。配合 Scheme 强大的表达能力和基于宏的元编程能力,在 Scheme 侧进行更高抽象层次的业务逻辑表达,可能更有优势。就像现在的游戏界,C/C++ 提供基础支持,Lua 负责游戏业务逻辑。 以此为假设,作为应用的嵌入式语言,一个 Scheme 实现需要具备以下特点: - 与宿主语言便利交互。比如,用 Rust 实现的 Scheme 需要提供方便的 Rust API,用 Swift 实现的 Scheme 需要提供方便的 Swift API。仅仅提供传统的 C FFI 是远远不够的。我们需要方便地将应用的基础功能作为库暴露给 Scheme 使用。 - 可配置的 capability。作为应用的嵌入式语言,我们不希望它内置过多的能力,比如,我们往往需要禁止它任意访问网络、或本地文件系统。随着应用启动 Scheme 解释器时,要按需配置可用的标准库。这一点上,Scheme 的极简特性是个优势,它的标准库很小,容易处理。 - 良好的 debug 工具。Scheme 代码 debug 本就麻烦,特别是涉及宏的场景。与宿主应用的交互又增加了一层复杂度,debug 体验变得更加重要。 - gas/fuel 计费系统。如果要将扩展能力开放给普通用户,需要增加 gas/fuel 系统,避免用户写出死循环或者高耗时代码,影响主应用体验。 - 高性能不是必选项,简洁易懂、符合标准、代码量小的 Scheme 实现,更容易获得信任。