解决Scheme中custom-cons在过程内的语法关键字引用错误
问题:如何让自定义语法
custom-cons在过程内正常工作? 最小工作代码示例
(define (demo-tree) (custom-cons 0 1)) (define-syntax custom-cons (syntax-rules () ( ; (_ x y) (custom-cons x y) (cons-stream x y) ))) (custom-cons 0 1) (demo-tree) (custom-cons 0 1)
问题现象
仅调用(demo-tree)时会报错:;;Variable reference to a syntactic keyword: custom-cons,其余直接调用(custom-cons 0 1)的情况均可正常运行。
问题原因
代码顺序错误:先定义了过程demo-tree,此时custom-cons还未被定义为宏,过程内的custom-cons被标记为普通变量;后续定义custom-cons宏后,顶层的调用会被正确展开,但已定义完成的demo-tree过程不会重新触发宏展开——因为过程在定义时已完成编译,内部代码不会再被宏处理器识别。
另外要明确:define-syntax定义的是句法关键字,这类关键字仅在代码的编译/加载阶段被宏展开器处理,运行时过程体内的代码不会触发宏展开,因此如果过程定义时宏尚未存在,就会出现变量引用错误。
解决方法
调整代码顺序,先定义宏,再定义使用该宏的过程,修正后的代码如下:
; 先定义custom-cons宏 (define-syntax custom-cons (syntax-rules () ((custom-cons x y) (cons-stream x y)))) ; 再定义依赖该宏的过程 (define (demo-tree) (custom-cons 0 1)) ; 测试调用 (custom-cons 0 1) (demo-tree) (custom-cons 0 1)
这样在定义demo-tree时,custom-cons已经是已知的句法关键字,宏展开器会在过程编译阶段就把(custom-cons 0 1)替换成(cons-stream 0 1),运行时就不会出现变量引用错误了。
内容的提问来源于stack exchange,提问作者An5Drama
相关产品推荐
相关产品推荐

