背景介绍
标题:Monkey The programming language that lives in books
原文链接
初读此文,还以为是这是一篇调侃程序猿的文章呢,怎么会有一种编程语言叫 “Monkey” 呢?搜索了一下,恕我孤陋寡闻了,的确有这样一门语言。正如标题所言,这是一种存在于书本上的编程语言,所以鲜有人知。
现在也有一些程序的命名中带有 Monkey 的,如 Android 系统自带的 Monkey 程序,MonkeyRunner 等,但是它们和本文讨论的不是一个概念。Monkey 是一种类似 JavaScript 的语言,至于为什么没有流行起来呢,不得而知。
看完该文,我的感觉是 Monkey 还是一个很新的语言,需要自己实现,学习者可以实现成解释型语言,也可以基于字节码和虚拟机来构建它,可能主要时用以学习和研究的吧。如果能搞清楚这门语言,说不定也自己发明一种新语言呢!
什么是 Monkey
Monkey is a programming language that you can build yourself by reading through Writing An Interpreter In Go and Writing A Compiler In Go.
Monkey 是一种编程语言,你可以通过阅读 《用 Go 语言写一个解释器》 和 《用 Go 语言写一个编译器》 这两本书来自己构建 Monkey 语言。
目前,Monkey 语言还没有正式被实现,它存在于书本上,实现它完全由您、广大读者们决定。它可以作为一种树形解释器实现,也可以基于字节码编译器和虚拟机实现。(补充理解:译者认为这里是在说 Monkey 编写的程序是如何运行的,是像 JS 那样基于解释器执行呢,或者像 Java 那样基于虚拟机字节码运行。)
通常, Monkey 语言编写的代码长这样:
// 数值或者数学表达式...
let version = 1 + (50 / 2) - (8 * 3);
// ... 字符串定义
let name = "The Monkey programming language";
// ... 布尔定义
let isMonkeyFastNow = true;
// ... 数组和哈希 Map
let people = [{"name": "Anna", "age": 24}, {"name": "Bob", "age": 99}];
它还可以定义函数:
// User-defined functions...
let getName = fn(person) { person["name"]; };
getName(people[0]); // => "Anna"
getName(people[1]); // => "Bob"
// and built-in functions
puts(len(people)) // prints: 2
并且也有条件分支,显式或者隐式的返回值、递归函数等,这意味着我们可以用 Monkey 这样写:
let fibonacci = fn(x) {
if (x == 0) {
0
} else {
if (x == 1) {
return 1;
} else {
fibonacci(x - 1) + fibonacci(x - 2);
}
}
};
但是,对每种 Monkey 实现来说,其镇山之宝是闭包。
// `newAdder` returns a closure that makes use of the free variables `a` and `b`:
let newAdder = fn(a, b) {
fn(c) { a + b + c };
};
// This constructs a new `adder` function:
let adder = newAdder(1, 2);
adder(8); // => 11
Monkey 标准
《用 Go 语言写一个解释器》 发布于 2016 年,最新的版本是 2019 年发布的,版本号为 1.6 。
Monkey 标准的第一本书定义了 Monkey 的语法,并且描述了它作为一种树形解释器必须包含的特征:
- 数值、布尔、字符串、数组和哈希 Map
- REPL (全称:Read-eval-print-loop ),即交互式解析器
- 数学表达式
- 一类和高阶函数
- 内置函数
- 递归
- 闭包
《遗失的章节:一个 Monkye 的宏系统》 这本书发布于 2017 年,作为一个免费的资料库指导人们如何使用 Go 语言编写 Monkey 解释器。它可以被认为是《用 Go 语言写一个解释器》 这本书第五章节的内容,因为它直接建立在前面四章的基础上,并且在书中的末尾扩展了 Monkey 解释器。
《遗失的章节:一个 Monkye 的宏系统》 为 Monkey 添加了一个 “全天候” 、 lisp 风格的宏系统,这与 Elixir 的宏系统的工作方式很接近。
《用 Go 语言写一个编译器》 是在 2018 年发布的,最新版本是 2019 年新出的 1.1 。它与《用 Go 语言写一个解释器》 这本书是等价的,因为它没有改变语法,也没有添加任何新特性,它只是将 Monkey 的实现从一个遍历树的解释器变成一个字节码编译器和虚拟机。类似与从解释型语言(如 JavaScript )转换为字节码运行语言( 如 Java )。
从该书的结尾来看,除了速度提升了三倍以上之外,Monkey 的表现和行为跟《用 Go 语言写一个解释器》这本书结尾描述的没什么两样!
世界各地的 Monkey 迷们
有些读者在阅读本书时喜欢绕道而行:一种不同的实现语言、一些新特性、语法上的一些变化。由于书中展示的代码是 MIT 授权的,每个人都随心所欲地构建自己的 Monkey 实现,并向世界上其他地方的人们展示。
这里收集了一些有趣而且很酷的 Monkey 实现者与我分享的内容。
你也构建了自己的 Monkey 版本吗?让我知道吧,只要给我发邮件就可以了,我的邮箱是:me @ thorstenball.com 。
- Monkey 在 Elixir 中实现
- Rust 语言实现的 Monkey
- Monkey 的 C++ 实现
- 用 Go 语言一步一步实现 Monkey
- Typescript 完整实现 Monkey
- C# 方式实现的 Monkey
- Dart实现的解释型 Monkey
其他实现项目: