Racket中define-type语法疑问:需冒号分隔ID与类型?带问号类型不可用?
关于PLAI书中代码与新版plai-typed兼容问题的解答
1. 书中示例并非“错误”,是版本迭代导致的语法差异
《Programming Languages: Application and Interpretation》早期版本配套的是旧版PLAI库(基于plt-scheme时代的实现),而你现在安装的plai-typed是后续更新后的版本,语法规则做了调整,更贴合现代Racket的类型系统设计,所以书中原始写法和新版库不兼容,并非示例本身有误。
2. 如何让Racket兼容书中的原始写法?
可以安装对应书中版本的旧版PLAI库,步骤如下:
- 打开Racket的包管理器(Package Manager),搜索
plai(注意不是plai-typed),选择对应书版本的旧版安装(比如第一版对应的plai1.x版本) - 或者用命令行执行:
raco pkg install plai@1.1 - 安装完成后,将代码开头的
#lang plai-typed替换为#lang plai,就能直接运行书中的原始代码,无需修改。
3. 如果坚持使用新版plai-typed,必须修改书中示例吗?
是的,需要针对性修改语法差异点,主要调整包括:
- define-type写法:旧版用
类型名?作为类型标识,字段直接跟谓词(如number?);新版去掉类型名后的?,字段与类型之间加冒号,使用类型名(如number)而非谓词。比如你修改的AE类型定义就是正确的新版写法。 - 函数类型标注:旧版可能写
(define (interp a AE?) : number ...),新版需要改为(define (interp [a AE]) : number ...),参数的类型标注放在方括号内。 - 模式匹配与谓词:新版自动生成的构造器谓词(如
num?、add?)和旧版一致,但类型引用时不再带?。
并非书中所有示例都需要修改,比如纯Scheme逻辑的代码(如递归计算逻辑)大多可以直接复用,主要调整类型相关的语法即可。
内容的提问来源于stack exchange,提问作者Roger Costello
相关产品推荐
相关产品推荐

