为什么 Janet?(2023)
语法、Lisp 风格与可读性
- 许多人喜欢 Janet “现代化 Lisp” 的命名(
fn、first、do、set)以及一致的 s-expression,尤其适合树、JSON、DSL。 - 也有人仍然非常不喜欢 Lisp 的括号,觉得它们难以阅读/编辑,尤其是在数学较多或表达式很长时。
- 一些人认为,考虑到优秀的编辑器(Parinfer、结构化编辑),语法方面的抱怨被夸大了,而且所有主流语言在不同方面都有丑陋或不一致的语法。
- 用方括号表示参数和向量(类似 Clojure)的做法很有争议;有人一旦学会后觉得这种约定很优雅,另一些人则始终无法接受。
性能与实现
- 据说 Janet 的性能大致处于 Lua(PUC-Rio)这个区间;一些基准测试显示,它在长时间运行时比 Python 快约 5–10 倍,在 LuaJIT 上比 Fennel 略慢,甚至在一些小型、编译时工作量较大的任务上能胜过 Go。
- 它有一个线程化的字节码虚拟机;虽然不是 JIT 级别,但被认为对脚本和小工具来说已经“足够快”。
- 全局状态是线程本地的;每个线程一个
janet_init()。它是否适合复杂的多解释器/多线程嵌入场景(例如音频插件)存在争议。
宏、DSL 与编译期能力
- 宏和同像性是其主要吸引力之一。例子包括中缀数学 DSL、类似 SQL/数据框的查询 DSL、APL/J 风格的向量化,以及 Web 查询 DSL。
- Janet 很容易把大量工作移到编译期(例如把大型数据表作为字面量结构嵌入二进制文件)。
- 一些人强调,“Lisp 时刻”来自 REPL 驱动开发、结构化编辑以及把代码当数据,而不只是宏本身。
解析:PEG vs 正则表达式
- Janet 倡导使用基于 PEG 的文本解析,而不是正则表达式。
- 支持者认为 PEG 对复杂语法更清晰、更强大。
- 批评者称 PEG 是一条“进化死胡同”,指出存在非交换性的替代方案以及棘手的调试问题,并指出真实语法会暴露解析器的弱点。
- 另一些人反驳说,正则引擎也有依赖顺序的行为和回溯痛点。
可嵌入性、沙箱与使用场景
- 可嵌入性是其关键卖点;人们将 Janet 用于脚本、带嵌入脚本的标记、游戏引擎、Web 服务以及小型二进制程序。
- 内置沙箱功能(可不可逆地禁用某些特性集)因能安全嵌入不可信代码或限制工具能力而受到称赞。
- 内置网络功能和 shell DSL 使它作为
sh/Python/awk 的替代品,特别适合更大的系统脚本。
生态、工具与比较
- 优点:核心小而简单;启动快;可构建静态二进制;社区文档和教程不错;有真实的生产使用案例(Web 应用、工具、艺术软件)。
- 缺点:库生态有限(例如 HTTP 工具、TLS、路由);包版本管理较弱;以及对“不可变集合”的一些困惑,因为标准库返回的东西往往实际上是可变的。
- 常被拿来与 Clojure(不可变性、数据导向)、Lua/Fennel(可嵌入性、速度)、Tcl(DSL、脚本)和 Babashka(shell 脚本)比较。偏好因平台、数据处理需求以及启动/性能权衡而异。
AI、社区与元讨论
- 一大段子讨论转向“无 AI 社区”、垃圾信息/机器人防御(信任网络、身份验证、付费墙),以及 AI 如何影响排行榜和论坛。
- 一些人赞赏有人类管理的空间,并表达对 LLM 生成内容的意识形态反对;另一些人则觉得彻底封禁或纯度测试会令人疏远。