用 1024 字节制作一个 Python 解释器
一个 1,024 字节的 C“Python 解释器”只运行了一个极小、精心挑选的 Python 子集,引发了关于“真正实现一门语言”和“仅仅模仿其表面语法”之间界限的讨论。评论者探讨了极限代码高尔夫背后的取舍:省略错误检查、限制功能、通过反复重新解析源码来节省字节,并将这个项目与 SectorLISP、Tiny BASIC 等极简系统,以及 Snek 这类嵌入式语言进行比较。对话中很大一部分集中在缩进敏感语法、制表符/空格处理和工具链约束如何让语言设计与现实可维护性都变得复杂,即使在玩具解释器里也是如此。
空白符、制表符与空格,以及缩进语义
- 大量分支讨论认为,Python 风格的显著缩进是否真的会让词法分析变得复杂。
- 一种观点是:缩进确实会迫使词法语法不再是正则的,并需要一个缩进层级栈,但这仍然是可管理的,复杂度也与其他特性引入的复杂度相当(例如字符串插值)。
- 关于制表符与空格的争论很大:
- 有些人主张严格规则(不混用,或“先制表符后空格,但绝不能先空格后制表符”),并把异常模式视为错误。
- 另一些人反驳说,这类限制是任意的、带有文化偏见的(涉及 Unicode 空白符),而且如果把缩进建模为“栈上的前缀字符串”,技术上并非必需。
- 讨论了几个具体的失败案例:不同编辑器中混用制表符/空格、编辑器用制表符自动对齐,以及 Lisp 或 F# 风格代码中缩进与对齐之间的歧义。
- 总体分歧是:“缩进只用制表符、对齐只用空格”与“干脆禁止制表符、只用空格以避免工具链 bug”。
1024 字节解释器的范围与性质
- 多位评论者强调,这只是一个极小、极度简化、且容易出错的 类 Python 子集,而不是真正的 Python 实现。
- 它用单个字符做控制结构的模式匹配(任何 “f” 都当作
for,任何 “p” 都当作print等),所以非常不像 Python 的语法也仍然可能“运行”。 - 有人认为这太“恶心”或有误导性;也有人认为这对于一个刻意为之的代码高尔夫玩具来说是合理边界内的做法。
实现技巧与约束
- 循环通过跳回去并在每次迭代重新解析源码来实现,让人联想到早期 BASIC 或 DOS batch 解释器。
- 解释器直接对源文本操作,而不是构建 AST,这与老式 8 位解释器技术一致。
- 为了满足字节预算,错误检查大多被移除;有人称这算“作弊”,因为正确性于是依赖于人类作者。
相关项目与历史背景
- 评论者链接并比较了 SectorLISP、SectorC、Snek、Forth、J 的微型解释器,以及 Tiny BASIC / 早期 Microsoft BASIC 和 Turbo Pascal,指出过去很多东西都能塞进几千字节。
感知价值与动机
- 许多人称赞这篇文章、展开版本的可读性,以及代码高尔夫和 sizecoding 带来的乐趣与好奇心。
- 怀疑者质疑其实用性,认为二进制大小会是更诚实的衡量标准,或者建议直接让 AI 生成这种代码;而另一些人则为“手工完成”辩护,认为这正是其中的意义。