Scheme实现中letrec可否与letrec*一致?是否符合Scheme标准要求?
问题解答
完全可以这么做,该实现方式符合Scheme标准的相关规定。
核心原因
- Scheme标准(包括R6RS、R7RS)中仅规定
letrec的所有绑定的作用域覆盖整个letrec表达式,且所有初始化表达式的求值结果,要在全部求值完成后再统一赋值给对应绑定,没有对初始化表达式的求值顺序做强制约束。 letrec*相比letrec新增的约束只有「初始化表达式必须严格按照绑定书写的从左到右顺序求值,每完成一个表达式的求值就立刻给对应绑定赋值」,这种语义本身就是letrec合法实现的一种,不存在违反标准的情况。
实际影响
你这么实现之后,原本所有符合标准letrec语义的代码都可以正常运行,行为和标准要求完全一致。唯一的区别是你的实现会额外兼容一些依赖letrec*语义的代码,比如:
;; 该代码在标准letrec定义中属于未定义行为,在你实现的letrec中会稳定返回10 (letrec ((a 5) (b (+ a 5))) b)
这种对标准未定义行为给出明确、合理的处理,属于Scheme标准允许的实现扩展,完全合规。事实上目前已经有多个主流Scheme实现采用了这种处理方式。
内容的提问来源于stack exchange,提问作者Flux
相关产品推荐
相关产品推荐

