用 48 小时编写你的 Scheme 解释器/总结
你现在拥有一个可以运行的 Scheme 解释器,它实现了大部分的标准,包括函数、lambda 表达式、词法作用域、符号、字符串、整数、列表操作和赋值。你可以以交互式方式使用它,使用 REPL 或批处理模式,运行脚本文件。你可以编写 Scheme 函数库,并将它们包含在程序中或加载到交互式解释器中。通过一些 awk 或 sed 的文本处理,你可以将 UNIX 命令的输出格式化为带括号的 Lisp 列表,将其读取到 Scheme 程序中,并将此解释器用于 shell 脚本。
你还可以在这个解释器中添加一些特性。卫生宏允许你在代码执行之前对其进行转换。对于添加新的语言特性来说,这是一个非常方便的功能,并且 Scheme 的几个标准部分(例如 let 绑定和额外的控制流特性)都是用它们定义的。R5RS 的第 4.3 节定义了宏系统的语法和语义,并且有一个关于实现的完整的论文集。基本上,你想要在 readExpr 和 eval 之间插入一个函数,它接收一个表达式和一个宏环境,查找转换关键字,然后根据模式语言的规则对其进行转换,并根据需要重写变量。
延续是一种捕获“计算的剩余部分”,将其保存,并可能执行多次的方法。使用它们,你几乎可以在每种主要编程语言中实现每种控制流特性。实现延续的最简单方法是将程序转换为延续传递风格,以便 eval 接收一个额外的延续参数并调用它,而不是返回一个结果。这个参数将贯穿所有对 eval 的递归调用,但只有在评估对 call-with-current-continuation 的调用时才会被操作。
dynamic-wind 可以通过保存一个在离开当前延续时要执行的函数堆栈以及在恢复延续时要执行的函数堆栈(在延续数据类型内部存储)来实现。
如果你只是想学习更多关于 Haskell 的知识,有许多库可以帮助你。
- 对于 Web 应用程序:WASH,一个单子 Web 框架。
- 对于数据库:haskelldb,一个将 SQL 封装为一组 Haskell 函数的库,让你在查询数据库时获得语言的所有类型安全性。
- 对于 GUI 编程:Fudgets 和 wxHaskell。wxHaskell 更像是一个传统的 MVC GUI 库,而 Fudgets 包含了许多关于如何在函数式编程语言中表示 GUI 的新研究。
- 对于并发:软件事务内存,在论文可组合内存事务中描述。
- 对于网络:GHC 的网络库。
这将为你提供一个开始进一步研究这门语言的起点。快乐编程!
感谢 Ketil Malde、Pete Kazmier 和 Brock 发送关于本教程的问题和建议。其他评论、澄清和更正应在本教程的讨论页面上进行。